diff --git a/projects/mtg/include/AIPlayer.h b/projects/mtg/include/AIPlayer.h index f90644158..25adca748 100644 --- a/projects/mtg/include/AIPlayer.h +++ b/projects/mtg/include/AIPlayer.h @@ -1,62 +1,62 @@ -/* -* Wagic, The Homebrew ?! is licensed under the BSD license -* See LICENSE in the Folder's root -* http://wololo.net/wagic/ -*/ - -#ifndef _IAPLAYER_H -#define _IAPLAYER_H - -#include "Player.h" - - -#define INFO_NBCREATURES 0 -#define INFO_CREATURESPOWER 1 - - -class AIStats; - -class AIPlayer: public Player{ -protected: - MTGCardInstance * nextCardToPlay; - ManaCost * potentialMana; - void tapLandsForMana(ManaCost * potentialMana, ManaCost * cost); - int checkInterrupt(); - int combatDamages(); - int chooseAttackers(); - int chooseBlockers(); - int effectBadOrGood(MTGCardInstance * card); - int getCreaturesInfo(Player * player, int neededInfo = INFO_NBCREATURES , int untapMode = 0, int canAttack = 0); - AIStats * getStats(); -public: - virtual int displayStack(){return 0;} - AIStats * stats; - ManaCost * getPotentialMana(); - AIPlayer(MTGPlayerCards * _deck, string deckFile); - virtual ~AIPlayer(); - virtual MTGCardInstance * chooseCard(TargetChooser * tc, MTGCardInstance * source, int random = 0); - virtual int chooseTarget(TargetChooser * tc = NULL); - virtual int Act(float dt); - int isAI(){return 1;}; - -}; - - -class AIPlayerBaka: public AIPlayer{ -protected: - int oldGamePhase; - int timer; - MTGCardInstance * FindCardToPlay(ManaCost * potentialMana, const char * type); -public: - AIPlayerBaka(MTGPlayerCards * _deck, char * deckFile); - virtual int Act(float dt); - void initTimer(); -}; - -class AIPlayerFactory{ - public: - AIPlayer * createAIPlayer(MTGAllCards * collection, MTGPlayerCards * oponents_deck); -}; - - -#endif +/* + * Wagic, The Homebrew ?! is licensed under the BSD license + * See LICENSE in the Folder's root + * http://wololo.net/wagic/ + */ + +#ifndef _IAPLAYER_H +#define _IAPLAYER_H + +#include "Player.h" + + +#define INFO_NBCREATURES 0 +#define INFO_CREATURESPOWER 1 + + +class AIStats; + +class AIPlayer: public Player{ + protected: + MTGCardInstance * nextCardToPlay; + ManaCost * potentialMana; + void tapLandsForMana(ManaCost * potentialMana, ManaCost * cost); + int checkInterrupt(); + int combatDamages(); + int chooseAttackers(); + int chooseBlockers(); + int effectBadOrGood(MTGCardInstance * card); + int getCreaturesInfo(Player * player, int neededInfo = INFO_NBCREATURES , int untapMode = 0, int canAttack = 0); + AIStats * getStats(); + public: + virtual int displayStack(){return 0;} + AIStats * stats; + ManaCost * getPotentialMana(); + AIPlayer(MTGPlayerCards * _deck, string deckFile); + virtual ~AIPlayer(); + virtual MTGCardInstance * chooseCard(TargetChooser * tc, MTGCardInstance * source, int random = 0); + virtual int chooseTarget(TargetChooser * tc = NULL); + virtual int Act(float dt); + int isAI(){return 1;}; + +}; + + +class AIPlayerBaka: public AIPlayer{ + protected: + int oldGamePhase; + int timer; + MTGCardInstance * FindCardToPlay(ManaCost * potentialMana, const char * type); + public: + AIPlayerBaka(MTGPlayerCards * _deck, char * deckFile); + virtual int Act(float dt); + void initTimer(); +}; + +class AIPlayerFactory{ + public: + AIPlayer * createAIPlayer(MTGAllCards * collection, MTGPlayerCards * oponents_deck); +}; + + +#endif diff --git a/projects/mtg/include/AIStats.h b/projects/mtg/include/AIStats.h index 0b2283f0f..73a74a083 100644 --- a/projects/mtg/include/AIStats.h +++ b/projects/mtg/include/AIStats.h @@ -1,42 +1,42 @@ -#ifndef _AISTATS_H_ -#define _AISTATS_H_ - -#define STATS_PLAYER_MULTIPLIER 15 -#define STATS_CREATURE_MULTIPLIER 10 -#define STATS_AURA_MULTIPLIER 9 +#ifndef _AISTATS_H_ +#define _AISTATS_H_ + +#define STATS_PLAYER_MULTIPLIER 15 +#define STATS_CREATURE_MULTIPLIER 10 +#define STATS_AURA_MULTIPLIER 9 #include #include -using std::list; -using std::string; -class Player; -class MTGCardInstance; -class MTGCard; -class Damage; - -class AIStat{ -public: - int source; //MTGId of the card - int value; - int occurences; - bool direct; - AIStat(int _source, int _value, int _occurences, bool _direct):source(_source), value(_value),occurences(_occurences),direct(_direct){}; -}; - - - -class AIStats{ -public: - Player * player; - string filename; - list stats; - AIStats(Player * _player, char * filename); - ~AIStats(); - void updateStats(); - void load(char * filename); - void save(); - AIStat * find(MTGCard * card); - bool isInTop(MTGCardInstance * card, unsigned int max, bool tooSmallCountsForTrue = true ); - void updateStatsCard(MTGCardInstance * cardInstance, Damage * damage, float multiplier = 1.0); -}; - +using std::list; +using std::string; +class Player; +class MTGCardInstance; +class MTGCard; +class Damage; + +class AIStat{ + public: + int source; //MTGId of the card + int value; + int occurences; + bool direct; + AIStat(int _source, int _value, int _occurences, bool _direct):source(_source), value(_value),occurences(_occurences),direct(_direct){}; +}; + + + +class AIStats{ + public: + Player * player; + string filename; + list stats; + AIStats(Player * _player, char * filename); + ~AIStats(); + void updateStats(); + void load(char * filename); + void save(); + AIStat * find(MTGCard * card); + bool isInTop(MTGCardInstance * card, unsigned int max, bool tooSmallCountsForTrue = true ); + void updateStatsCard(MTGCardInstance * cardInstance, Damage * damage, float multiplier = 1.0); +}; + #endif diff --git a/projects/mtg/include/ActionElement.h b/projects/mtg/include/ActionElement.h index aacfe8e59..3c7d5ff8e 100644 --- a/projects/mtg/include/ActionElement.h +++ b/projects/mtg/include/ActionElement.h @@ -1,8 +1,8 @@ -/* -* Wagic, The Homebrew ?! is licensed under the BSD license -* See LICENSE in the Folder's root -* http://wololo.net/wagic/ -*/ +/* + * Wagic, The Homebrew ?! is licensed under the BSD license + * See LICENSE in the Folder's root + * http://wololo.net/wagic/ + */ #ifndef _ACTIONELEMENT_H_ #define _ACTIONELEMENT_H_ @@ -18,30 +18,30 @@ class Targetable; class TargetChooser; class ActionElement: public JGuiObject{ -protected: - int activeState; - + protected: + int activeState; -public: - TargetChooser * tc; - int currentPhase; - int newPhase; - int modal; - int waitingForAnswer; + + public: + TargetChooser * tc; + int currentPhase; + int newPhase; + int modal; + int waitingForAnswer; void RenderMessageBackground(float y0, int height); - int getActivity(); - virtual void Update(float dt){}; - virtual void Render(){}; - virtual int testDestroy(){return 0;}; - virtual int destroy(){return 0;}; - virtual void CheckUserInput(float dt){}; - ActionElement(int id); - virtual int isReactingToTargetClick(Targetable * card); - virtual int reactToTargetClick(Targetable * card); - virtual int isReactingToClick(MTGCardInstance * card){return 0;}; - virtual int reactToClick(MTGCardInstance * card){return 0;}; - virtual const char * getMenuText(){return "Ability";}; + int getActivity(); + virtual void Update(float dt){}; + virtual void Render(){}; + virtual int testDestroy(){return 0;}; + virtual int destroy(){return 0;}; + virtual void CheckUserInput(float dt){}; + ActionElement(int id); + virtual int isReactingToTargetClick(Targetable * card); + virtual int reactToTargetClick(Targetable * card); + virtual int isReactingToClick(MTGCardInstance * card){return 0;}; + virtual int reactToClick(MTGCardInstance * card){return 0;}; + virtual const char * getMenuText(){return "Ability";}; }; diff --git a/projects/mtg/include/ActionLayer.h b/projects/mtg/include/ActionLayer.h index 2eda20cbf..6a2ef7546 100644 --- a/projects/mtg/include/ActionLayer.h +++ b/projects/mtg/include/ActionLayer.h @@ -1,8 +1,8 @@ -/* -* Wagic, The Homebrew ?! is licensed under the BSD license -* See LICENSE in the Folder's root -* http://wololo.net/wagic/ -*/ +/* + * Wagic, The Homebrew ?! is licensed under the BSD license + * See LICENSE in the Folder's root + * http://wololo.net/wagic/ + */ #ifndef _ACTIONLAYER_H_ #define _ACTIONLAYER_H_ @@ -16,22 +16,22 @@ class Targetable; class ActionLayer: public GuiLayer, public JGuiListener{ public: - Targetable * menuObject; - SimpleMenu * abilitiesMenu; - virtual void Render(); - virtual void Update(float dt); - int unstopableRenderInProgress(); - void CheckUserInput(float dt); - ActionLayer(int id, GameObserver* _game):GuiLayer(id, _game){ menuObject = NULL; abilitiesMenu = NULL;}; - int isWaitingForAnswer(); - int isReactingToTargetClick(Targetable * card); - int reactToTargetClick(Targetable * card); - int isReactingToClick(MTGCardInstance * card); - int reactToClick(MTGCardInstance * card); - int isModal(); - void setMenuObject(Targetable * object); - void ButtonPressed(int controllerid, int controlid); - TargetChooser * getCurrentTargetChooser(); + Targetable * menuObject; + SimpleMenu * abilitiesMenu; + virtual void Render(); + virtual void Update(float dt); + int unstopableRenderInProgress(); + void CheckUserInput(float dt); + ActionLayer(int id, GameObserver* _game):GuiLayer(id, _game){ menuObject = NULL; abilitiesMenu = NULL;}; + int isWaitingForAnswer(); + int isReactingToTargetClick(Targetable * card); + int reactToTargetClick(Targetable * card); + int isReactingToClick(MTGCardInstance * card); + int reactToClick(MTGCardInstance * card); + int isModal(); + void setMenuObject(Targetable * object); + void ButtonPressed(int controllerid, int controlid); + TargetChooser * getCurrentTargetChooser(); }; diff --git a/projects/mtg/include/ActionStack.h b/projects/mtg/include/ActionStack.h index 15688cfa5..475401b15 100644 --- a/projects/mtg/include/ActionStack.h +++ b/projects/mtg/include/ActionStack.h @@ -1,151 +1,151 @@ -/* -* Wagic, The Homebrew ?! is licensed under the BSD license -* See LICENSE in the Folder's root -* http://wololo.net/wagic/ -*/ - -#ifndef _SPELLSTACK_H_ -#define _SPELLSTACK_H_ - -#define MAX_SPELL_TARGETS 10 - - -#define ACTION_SPELL 10 -#define ACTION_DAMAGE 11 -#define ACTION_DAMAGES 12 -#define ACTION_NEXTGAMEPHASE 13 -#define ACTION_DRAW 14 -#define ACTION_PUTINGRAVEYARD 15 -#define ACTION_ABILITY 16 - -#define NOT_RESOLVED -2 -#define RESOLVED_OK 1 -#define RESOLVED_NOK -1 - -#include "../include/PlayGuiObject.h" -#include "GuiLayers.h" -#include "../include/TargetsList.h" -#include "../include/Targetable.h" - -class GuiLayer; -class PlayGuiObject; -class MTGCardInstance; -class GameObserver; -class Player; -class Damageable; -class MTGAbility; -class Targetable; -class DamageStack; -class ManaCost; - - -#define ACTIONSTACK_STANDARD 0 -#define ACTIONSTACK_TARGET 1 - -class Interruptible: public PlayGuiObject, public Targetable{ -public: - int state, display; - MTGCardInstance * source; - virtual void Entering(){mHasFocus = true;}; - virtual bool Leaving(u32 key){mHasFocus = false;return true;}; - virtual bool ButtonPressed(){return true;}; - virtual int resolve(){return 0;}; - virtual void Render(){}; - int typeAsTarget(){return TARGET_STACKACTION;}; - Interruptible(int id,bool hasFocus = false):PlayGuiObject(id,40,x,y,hasFocus){state=NOT_RESOLVED;display=0;source=NULL;}; -}; - -class NextGamePhase: public Interruptible { -public: - int resolve(); - void Render(); - NextGamePhase(int id); -}; - -class Spell: public Interruptible, public TargetsList { -protected: - -public: - ManaCost * cost; - Spell(MTGCardInstance* _source); - Spell(int id, MTGCardInstance* _source, Targetable * _targets[], int _nbtargets, ManaCost * _cost); - ~Spell(); - int resolve(); - void Render(); -}; - -class StackAbility: public Interruptible { -public: - MTGAbility * ability; - int resolve(); - void Render(); - StackAbility(int id, MTGAbility * _ability); -}; - -class PutInGraveyard: public Interruptible { -public: - MTGCardInstance * card; - int removeFromGame; - int resolve(); - void Render(); - PutInGraveyard(int id, MTGCardInstance * _card); -}; - - -class DrawAction: public Interruptible { -public: - int nbcards; - Player * player; - int resolve(); - void Render(); - DrawAction(int id, Player * _player, int _nbcards); -}; - -class ActionStack :public GuiLayer{ -protected: - int interruptDecision[2]; - int timer; - int currentState; - int mode; - int checked; - - - void unpackDamageStacks(); - void unpackDamageStack(DamageStack * ds); - void repackDamageStacks(); -public: - int setIsInterrupting(Player * player); - int count( int type = 0 , int state = 0 , int display = -1); - Interruptible * getPrevious(Interruptible * next, int type = 0, int state = 0 , int display = -1); - int getPreviousIndex(Interruptible * next, int type = 0, int state = 0 , int display = -1); - Interruptible * getNext(Interruptible * previous, int type = 0, int state = 0 , int display = -1); - int getNextIndex(Interruptible * previous, int type = 0, int state = 0 , int display = -1); - void Fizzle(Interruptible * action); - Interruptible * _(int id); - void cancelInterruptOffer(int cancelMode = 1); - void endOfInterruption(); - Interruptible * getLatest(int state); - Player * askIfWishesToInterrupt; - int garbageCollect(); - int addAction(Interruptible * interruptible); - int addSpell(MTGCardInstance* card, Targetable * targets[], int nbtargets, ManaCost * mana); - int AddNextGamePhase(); - int addPutInGraveyard(MTGCardInstance * card); - int addDraw(Player * player, int nbcards = 1); - int addDamage(MTGCardInstance * _source, Damageable * target, int _damage); - int addAbility(MTGAbility * ability); - void Update(float dt); - void CheckUserInput(float dt); - virtual void Render(); - ActionStack(int id, GameObserver* _game); - int resolve(); - int CombatDamages(); - int CombatDamages(int firststrike); - int has(Interruptible * action); -}; - - - - - -#endif +/* + * Wagic, The Homebrew ?! is licensed under the BSD license + * See LICENSE in the Folder's root + * http://wololo.net/wagic/ + */ + +#ifndef _SPELLSTACK_H_ +#define _SPELLSTACK_H_ + +#define MAX_SPELL_TARGETS 10 + + +#define ACTION_SPELL 10 +#define ACTION_DAMAGE 11 +#define ACTION_DAMAGES 12 +#define ACTION_NEXTGAMEPHASE 13 +#define ACTION_DRAW 14 +#define ACTION_PUTINGRAVEYARD 15 +#define ACTION_ABILITY 16 + +#define NOT_RESOLVED -2 +#define RESOLVED_OK 1 +#define RESOLVED_NOK -1 + +#include "../include/PlayGuiObject.h" +#include "GuiLayers.h" +#include "../include/TargetsList.h" +#include "../include/Targetable.h" + +class GuiLayer; +class PlayGuiObject; +class MTGCardInstance; +class GameObserver; +class Player; +class Damageable; +class MTGAbility; +class Targetable; +class DamageStack; +class ManaCost; + + +#define ACTIONSTACK_STANDARD 0 +#define ACTIONSTACK_TARGET 1 + +class Interruptible: public PlayGuiObject, public Targetable{ + public: + int state, display; + MTGCardInstance * source; + virtual void Entering(){mHasFocus = true;}; + virtual bool Leaving(u32 key){mHasFocus = false;return true;}; + virtual bool ButtonPressed(){return true;}; + virtual int resolve(){return 0;}; + virtual void Render(){}; + int typeAsTarget(){return TARGET_STACKACTION;}; + Interruptible(int id,bool hasFocus = false):PlayGuiObject(id,40,x,y,hasFocus){state=NOT_RESOLVED;display=0;source=NULL;}; +}; + +class NextGamePhase: public Interruptible { + public: + int resolve(); + void Render(); + NextGamePhase(int id); +}; + +class Spell: public Interruptible, public TargetsList { + protected: + + public: + ManaCost * cost; + Spell(MTGCardInstance* _source); + Spell(int id, MTGCardInstance* _source, Targetable * _targets[], int _nbtargets, ManaCost * _cost); + ~Spell(); + int resolve(); + void Render(); +}; + +class StackAbility: public Interruptible { + public: + MTGAbility * ability; + int resolve(); + void Render(); + StackAbility(int id, MTGAbility * _ability); +}; + +class PutInGraveyard: public Interruptible { + public: + MTGCardInstance * card; + int removeFromGame; + int resolve(); + void Render(); + PutInGraveyard(int id, MTGCardInstance * _card); +}; + + +class DrawAction: public Interruptible { + public: + int nbcards; + Player * player; + int resolve(); + void Render(); + DrawAction(int id, Player * _player, int _nbcards); +}; + +class ActionStack :public GuiLayer{ + protected: + int interruptDecision[2]; + int timer; + int currentState; + int mode; + int checked; + + + void unpackDamageStacks(); + void unpackDamageStack(DamageStack * ds); + void repackDamageStacks(); + public: + int setIsInterrupting(Player * player); + int count( int type = 0 , int state = 0 , int display = -1); + Interruptible * getPrevious(Interruptible * next, int type = 0, int state = 0 , int display = -1); + int getPreviousIndex(Interruptible * next, int type = 0, int state = 0 , int display = -1); + Interruptible * getNext(Interruptible * previous, int type = 0, int state = 0 , int display = -1); + int getNextIndex(Interruptible * previous, int type = 0, int state = 0 , int display = -1); + void Fizzle(Interruptible * action); + Interruptible * _(int id); + void cancelInterruptOffer(int cancelMode = 1); + void endOfInterruption(); + Interruptible * getLatest(int state); + Player * askIfWishesToInterrupt; + int garbageCollect(); + int addAction(Interruptible * interruptible); + int addSpell(MTGCardInstance* card, Targetable * targets[], int nbtargets, ManaCost * mana); + int AddNextGamePhase(); + int addPutInGraveyard(MTGCardInstance * card); + int addDraw(Player * player, int nbcards = 1); + int addDamage(MTGCardInstance * _source, Damageable * target, int _damage); + int addAbility(MTGAbility * ability); + void Update(float dt); + void CheckUserInput(float dt); + virtual void Render(); + ActionStack(int id, GameObserver* _game); + int resolve(); + int CombatDamages(); + int CombatDamages(int firststrike); + int has(Interruptible * action); +}; + + + + + +#endif diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 8d724414c..2f406d3bd 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -1,2981 +1,2981 @@ -#ifndef _CARDS_H_ -#define _CARDS_H_ - -#include "MTGAbility.h" -#include "GroupOfCards.h" -#include "ManaCost.h" -#include "CardDescriptor.h" -#include "AIPlayer.h" -#include "CardDisplay.h" -#include "Subtypes.h" -#include "CardGui.h" - -#include -#include - - -#include -using std::map; - -/* -Generic classes -*/ - - -//Drawer, allows to draw a card for a cost: - -class ADrawer:public ActivatedAbility{ -public: - int nbcards; - ADrawer(int _id, MTGCardInstance * card,ManaCost * _cost, int _nbcards = 1, int _tap = 1):ActivatedAbility(_id, card,_cost,0,_tap),nbcards(_nbcards){ - } - - int resolve(){ - game->mLayers->stackLayer()->addDraw(source->controller(),nbcards); - return 1; - } -}; - - -//Destroyer. TargetAbility -class ADestroyer:public TargetAbility{ -public: - int bury; - ADestroyer(int _id, MTGCardInstance * _source, TargetChooser * _tc = NULL, int _bury = 0):TargetAbility(_id,_source, tc),bury(_bury){ - if (!tc) tc = NEW CreatureTargetChooser(); - } - - int resolve(){ - MTGCardInstance * _target = tc->getNextCardTarget(); - if(_target){ - if (bury){ - _target->controller()->game->putInGraveyard(_target); - }else{ - game->mLayers->stackLayer()->addPutInGraveyard(_target); - } - return 1; - } - return 0; - } - -}; - -//Destroyer. TargetAbility -class ABurier:public ADestroyer{ -public: - ABurier(int _id, MTGCardInstance * _source, TargetChooser * _tc = NULL):ADestroyer(_id,_source, tc,1){ - } -}; - - -/*Changes one of the basic abilities of target -source : spell -target : spell target (creature) -modifier : 1 to add the ability, 0 to remove it -_ability : Id of the ability, as described in mtgdefinitions -*/ -class ABasicAbilityModifier:public MTGAbility{ -public: - int modifier; - int ability; - int value_before_modification; - ABasicAbilityModifier(int _id, MTGCardInstance * _source, MTGCardInstance * _target, int _ability, int _modifier = 1): MTGAbility(_id,_source,_target),modifier(_modifier),ability(_ability){ - value_before_modification = ((MTGCardInstance * )target)->basicAbilities[ability]; - ((MTGCardInstance * )target)->basicAbilities[ability]=modifier; - } - - int destroy(){ - if (((MTGCardInstance * )target)->basicAbilities[ability] == modifier){ - ((MTGCardInstance * )target)->basicAbilities[ability] = value_before_modification; - return 1; - }else{ - //BUG !!! - return 0; - } - } -}; - -//Modifies an ability until end of turn. Needs a target -class ABasicAbilityModifierUntilEOT:public TargetAbility{ - public: - MTGCardInstance * mTargets[50]; - int nbTargets; - int modifier; - int stateBeforeActivation[50]; - int ability; - ABasicAbilityModifierUntilEOT(int _id, MTGCardInstance * _source, int _ability, ManaCost * _cost, TargetChooser * _tc = NULL, int _modifier = 1): TargetAbility(_id,_source,_cost),modifier(_modifier), ability(_ability){ - nbTargets = 0; - tc = _tc; - if (!tc) tc = NEW CreatureTargetChooser(_source); - } - - void Update(float dt){ - if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP){ - for (int i = 0; i < nbTargets; i++){ - MTGCardInstance * mTarget = mTargets[i]; - if(mTarget && mTarget->basicAbilities[ability]){ - mTarget->basicAbilities[ability] = stateBeforeActivation[i]; - } - } - nbTargets = 0; - } - TargetAbility::Update(dt); - } - - - int resolve(){ - MTGCardInstance * mTarget = tc->getNextCardTarget(); - if (mTarget){ - mTargets[nbTargets] = mTarget; - stateBeforeActivation[nbTargets] = mTarget->basicAbilities[ability]; - mTarget->basicAbilities[ability] = modifier; - nbTargets++; - } - return 1; - } - - -}; - -/*Instants that modifies a basic ability until end of turn */ -class AInstantBasicAbilityModifierUntilEOT: public InstantAbility{ -public: - int stateBeforeActivation; - int ability; - AInstantBasicAbilityModifierUntilEOT(int _id, MTGCardInstance * _source, MTGCardInstance * _target, int _ability, int value):InstantAbility(_id, _source, _target),ability(_ability){ - stateBeforeActivation = _target->basicAbilities[ability]; - _target->basicAbilities[ability] = value; - } - - int destroy(){ - ((MTGCardInstance *)target)->basicAbilities[ability] = stateBeforeActivation; - return 1; - } - -}; - -//Alteration of Ability until of turn (Aura) -class ABasicAbilityAuraModifierUntilEOT: public ActivatedAbility{ -public: - int stateBeforeActivation; - int ability; - int value; - ABasicAbilityAuraModifierUntilEOT(int _id, MTGCardInstance * _source, MTGCardInstance * _target, ManaCost * _cost, int _ability, int _value = 1):ActivatedAbility(_id,_source, _cost, 0,0), ability(_ability), value(_value){ - target = _target; - stateBeforeActivation = _target->basicAbilities[ability]; - } - - void Update(float dt){ - if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP){ - MTGCardInstance * _target = (MTGCardInstance *) target; - _target->basicAbilities[ability] = stateBeforeActivation; - } - ActivatedAbility::Update(dt); - } - - int resolve(){ - MTGCardInstance * _target = (MTGCardInstance *) target; - stateBeforeActivation = _target->basicAbilities[ability]; - _target->basicAbilities[ability] = value; - return 1; - } - -}; - - - -/*Gives life each time a spell matching CardDescriptor's criteria are match . Optionnal manacost*/ -class ASpellCastLife:public MTGAbility{ -public: - CardDescriptor trigger; - ManaCost * cost; - int life; - MTGCardInstance * lastUsedOn; - MTGCardInstance * lastChecked; - ASpellCastLife(int id, MTGCardInstance * _source, CardDescriptor _trigger, ManaCost * _cost, int _life): MTGAbility(id, _source), trigger(_trigger), cost(_cost), life(_life){ - } - ASpellCastLife(int id, MTGCardInstance * _source, int color, ManaCost * _cost, int _life): MTGAbility(id, _source), cost(_cost), life(_life){ - trigger.setColor(color); - } - - int isReactingToClick(MTGCardInstance * _card){ - if (_card == source && game->currentlyActing()->game->inPlay->hasCard(source)){ - if (game->currentlyActing()->getManaPool()->canAfford(cost)){ - Interruptible * laststackitem = game->mLayers->stackLayer()->_(-1); - if (laststackitem && laststackitem->type == ACTION_SPELL){ - Spell * spell = (Spell*)laststackitem; - if (spell->source != lastUsedOn && trigger.match(spell->source)){ - lastChecked = spell->source; - return 1; - } - } - } - } - return 0; - } - - int reactToClick(MTGCardInstance * _card){ - if (!isReactingToClick( _card)) return 0; - game->currentlyActing()->getManaPool()->pay(cost); - game->currentlyActing()->life+=life; - lastUsedOn = lastChecked; - return 1; - } - -}; - -//Allows to untap at any moment for an amount of mana -class AUnBlocker:public MTGAbility{ -public: - ManaCost * cost; - AUnBlocker(int id, MTGCardInstance * _source, MTGCardInstance * _target, ManaCost * _cost):MTGAbility(id, _source, _target), cost(_cost){ - } - - - int isReactingToClick(MTGCardInstance * _card){ - if (_card == target && game->currentlyActing()->game->inPlay->hasCard(source) && (MTGCardInstance *) _card->isTapped()){ - if (game->currentlyActing()->getManaPool()->canAfford(cost)){ - return 1; - } - } - return 0; - } - - int reactToClick(MTGCardInstance * _card){ - if (!isReactingToClick( _card)) return 0; - game->currentlyActing()->getManaPool()->pay(cost); - _card->untap(); - return 1; - } -}; - -//Allows to untap target card once per turn for a manaCost -class AUntaperOnceDuringTurn:public AUnBlocker{ -public: - int untappedThisTurn; - int onlyPlayerTurn; - AUntaperOnceDuringTurn(int id, MTGCardInstance * _source, MTGCardInstance * _target, ManaCost * _cost, int _onlyPlayerTurn = 1):AUnBlocker(id, _source, _target, _cost){ - onlyPlayerTurn = _onlyPlayerTurn; - untappedThisTurn = 0; - } - - void Update(float dt){ - if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP) untappedThisTurn = 0; - AUnBlocker::Update(dt); - } - - int isReactingToClick(MTGCardInstance * card){ - if (onlyPlayerTurn && game->currentPlayer!=source->controller()) return 0; - if (untappedThisTurn) return 0; - return AUnBlocker::isReactingToClick(card); - } - - int reactToClick(MTGCardInstance * card){ - untappedThisTurn = 1; - return AUnBlocker::reactToClick(card); - } -}; - -//Alteration of Power and Toughness (enchantments) -class APowerToughnessModifier: public MTGAbility{ -public: - int power, toughness; - APowerToughnessModifier(int id, MTGCardInstance * _source, MTGCardInstance * _target, int _power, int _toughness):MTGAbility(id,_source,_target),power(_power),toughness(_toughness){ - _target->power += power; - _target->addToToughness(toughness); - } - - int destroy(){ - ((MTGCardInstance *)target)->power -= power; - ((MTGCardInstance *)target)->addToToughness(-toughness); - return 1; - } -}; - -// Permanent life alteration evry turn of the target's controller. Useful only for unstable mutation currently -class APowerToughnessModifierRegularCounter:public MTGAbility{ -public: - int power, toughness; - int phase; - APowerToughnessModifierRegularCounter(int id, MTGCardInstance * _source, MTGCardInstance * _target, int _phase, int _power, int _toughness):MTGAbility(id,_source,_target),power(_power),toughness(_toughness), phase(_phase){ - } - - void Update(float dt){ - if (newPhase !=currentPhase && newPhase==phase && game->currentPlayer==((MTGCardInstance *)target)->controller()){ - ((MTGCardInstance *)target)->power += power; - ((MTGCardInstance *)target)->addToToughness(toughness); - } - } - -}; - - -//Alteration of Power and Toughness until end of turn (TargetAbility) -// Gives +n/+m until end of turn to any card that's a target -class ATargetterPowerToughnessModifierUntilEOT: public TargetAbility{ -public: - MTGCardInstance * mTargets[50]; - int nbTargets; - int power, toughness; - - ATargetterPowerToughnessModifierUntilEOT(int _id, MTGCardInstance * _source, int _power, int _toughness, ManaCost * _cost, TargetChooser * _tc = NULL):TargetAbility(_id,_source,_tc,_cost,0),power(_power),toughness(_toughness){ - if (!tc) tc = NEW CreatureTargetChooser(_source); - nbTargets = 0; - } - - - void Update(float dt){ - if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP){ - for (int i = 0; i < nbTargets; i++){ - MTGCardInstance * mTarget = mTargets[i]; - if(mTarget){ - mTarget->power-=power; - mTarget->addToToughness(-toughness); - } - } - nbTargets = 0; - } - TargetAbility::Update(dt); - } - - - int resolve(){ - MTGCardInstance * mTarget = tc->getNextCardTarget(); - if (mTarget){ - mTargets[nbTargets] = mTarget; - mTarget->power+= power; - mTarget->addToToughness(toughness); - nbTargets++; - } - return 1; - } - -}; - - - -//Alteration of Power and Toughness until end of turn (Aura) -class APowerToughnessModifierUntilEndOfTurn: public MTGAbility{ -public: - int power, toughness; - int counters; - int maxcounters; - ManaCost * cost; - APowerToughnessModifierUntilEndOfTurn(int id, MTGCardInstance * _source, MTGCardInstance * _target, int _power, int _toughness, ManaCost * _cost, int _maxcounters = 0):MTGAbility(id,_source,_target),power(_power),toughness(_toughness),maxcounters(_maxcounters), cost(_cost){ - counters = 0; - } - - void Update(float dt){ - if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP){ - while(counters){ - ((MTGCardInstance *)target)->power -= power; - ((MTGCardInstance *)target)->addToToughness(-toughness); - counters--; - } - } - } - - int isReactingToClick(MTGCardInstance * _card){ - if (_card == source && (!maxcounters || counters < maxcounters) && game->currentlyActing()->game->inPlay->hasCard(source)){ - if (game->currentlyActing()->getManaPool()->canAfford(cost)){ - return 1; - } - } - return 0; - } - - int reactToClick(MTGCardInstance * _card){ - if (!isReactingToClick( _card)) return 0; - game->currentlyActing()->getManaPool()->pay(cost); - ((MTGCardInstance *)target)->power += power; - ((MTGCardInstance *)target)->addToToughness(toughness); - counters++; - return 1; - } -}; - - -//Alteration of Power and toughness until end of turn (instant) -class AInstantPowerToughnessModifierUntilEOT: public InstantAbility{ -public: - int power, toughness; - AInstantPowerToughnessModifierUntilEOT(int _id, MTGCardInstance * _source, MTGCardInstance * _target, int _power, int _toughness): InstantAbility(_id, _source, _target), power(_power), toughness(_toughness){ - } - - int resolve(){ - ((MTGCardInstance *)target)->power +=power; - ((MTGCardInstance *)target)->addToToughness(toughness); - return 1; - } - - int destroy(){ - ((MTGCardInstance *)target)->power -=power; - ((MTGCardInstance *)target)->addToToughness(-toughness); - return 1; - } - -}; -//Untap Blockers with simple Mana Mechanism -class AUntapManaBlocker: public Blocker{ -public: - AUntapManaBlocker(int id, MTGCardInstance * card, ManaCost * _cost):Blocker(id, card, _cost){ - } - - AUntapManaBlocker(int id, MTGCardInstance * card, MTGCardInstance * _target, ManaCost * _cost):Blocker(id, card,_target, _cost){ - } -}; - -/* Spell Counters (Enchantment) for a mana cost */ -//LifeForce -class ASpellCounterEnchantment:public TargetAbility{ -public: - - ASpellCounterEnchantment(int _id, MTGCardInstance * _source, ManaCost * _cost,int color = -1, int _tap = 0):TargetAbility(_id,_source,NEW SpellTargetChooser(_source,color),_cost,0,_tap){ - } - - int resolve(){ - Spell * _target = tc->getNextSpellTarget(); - if(_target){ - game->mLayers->stackLayer()->Fizzle(_target); - return 1; - } - return 0; - } - -}; - -/*Mana Producers (lands) -//These have a reactToClick function, and therefore two manaProducers on the same card conflict with each other -//That means the player has to choose one. although that is perfect for cards such as birds of paradise or badlands, -other solutions need to be provided for abilities that add mana (ex: mana flare) -*/ -/* -Currently the mana is added to the pool AFTER the animation -This is VERY BAD, since we don't have any control on the duration of the animation. This can lead to bugs with -the AI, who is expecting to have the mana in its manapool right after clicking the land card !!! -The sum of "dt" has to be 0.25 for the mana to be in the manapool currently -*/ - -class AManaProducer: public MTGAbility{ -protected: - ManaCost * cost; - ManaCost * output; - string menutext; - float x0,y0,x1,y1,x,y; - float animation; - Player * controller; - - hgeParticleSystem * mParticleSys; -public: - AManaProducer(int id, MTGCardInstance * card, ManaCost * _output, ManaCost * _cost = NULL ):MTGAbility(id, card){ - LOG("==Creating ManaProducer Object"); - cost = _cost; - output=_output; - x1 = 10; - y1 = 220; - Player * player = card->controller(); - if (player == game->players[1]) y1 = 100; - x = x1; - y = y1; - animation = 0.f; - mParticleSys = NULL; - menutext = ""; - - int landColor = output->getMainColor(); - - if (landColor == MTG_COLOR_RED){ - mParticleSys = NEW hgeParticleSystem("graphics/manared.psi",GameApp::CommonRes->GetQuad("particles")); - }else if (landColor == MTG_COLOR_BLUE){ - mParticleSys = NEW hgeParticleSystem("graphics/manablue.psi", GameApp::CommonRes->GetQuad("particles")); - }else if (landColor == MTG_COLOR_GREEN){ - mParticleSys = NEW hgeParticleSystem("graphics/managreen.psi", GameApp::CommonRes->GetQuad("particles")); - }else if (landColor == MTG_COLOR_BLACK){ - mParticleSys = NEW hgeParticleSystem("graphics/manablack.psi", GameApp::CommonRes->GetQuad("particles")); - }else if (landColor == MTG_COLOR_WHITE){ - mParticleSys = NEW hgeParticleSystem("graphics/manawhite.psi", GameApp::CommonRes->GetQuad("particles")); - }else{ - mParticleSys = NEW hgeParticleSystem("graphics/mana.psi", GameApp::CommonRes->GetQuad("particles")); - } - - - - LOG("==ManaProducer Object Creation successful !"); - } - - void Update(float dt){ - if (mParticleSys) mParticleSys->Update(dt); - if (animation){ - x = (1.f - animation)*x1 + animation * x0; - y = (1.f - animation)*y1 + animation * y0; - if (mParticleSys) mParticleSys->MoveTo(x, y); - if (mParticleSys && animation == 1.f) mParticleSys->Fire(); - animation -= 4 *dt; - if (animation < 0){ - animation = 0; - controller->getManaPool()->add(output); - if (mParticleSys) mParticleSys->Stop(); - } - } - - } - - void Render(){ - JRenderer * renderer = JRenderer::GetInstance(); - if (animation){ - renderer->SetTexBlend(BLEND_SRC_ALPHA, BLEND_ONE); - if (mParticleSys) mParticleSys->Render(); - // set normal blending - renderer->SetTexBlend(BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA); - } - - } - - int isReactingToClick(MTGCardInstance * _card){ - int result = 0; - if (_card == source && !source->isTapped() && game->currentlyActing()->game->inPlay->hasCard(source) && (source->hasType("land") || !source->hasSummoningSickness()) ){ - if (!cost || game->currentlyActing()->getManaPool()->canAfford(cost)) result = 1; - } - return result; - } - - int reactToClick(MTGCardInstance * _card){ - if (!isReactingToClick( _card)) return 0; - source->tapped = 1; - if (cost) GameObserver::GetInstance()->currentlyActing()->getManaPool()->pay(cost); - animation = 1.f; - CardGui * cardg = game->mLayers->playLayer()->getByCard(source); - if (cardg){ - x0 = cardg->x + 15; - y0 = cardg->y + 20; - } - controller = source->controller(); - return 1; - } - - const char * getMenuText(){ - if (menutext.size())return menutext.c_str(); - menutext = "Add "; - char buffer[128]; - int alreadyHasOne = 0; - for (int i= 0; i < 6; i++){ - int value = output->getCost(i); - if (value){ - if (alreadyHasOne) menutext.append(","); - sprintf(buffer, "%i ", value); - menutext.append(buffer); - switch (i){ - case MTG_COLOR_RED: - menutext.append("red"); - break; - case MTG_COLOR_BLUE: - menutext.append("blue"); - break; - case MTG_COLOR_GREEN: - menutext.append("green"); - break; - case MTG_COLOR_WHITE: - menutext.append("white"); - break; - case MTG_COLOR_BLACK: - menutext.append("black"); - break; - default: - break; - } - alreadyHasOne = 1; - } - } - menutext.append(" mana"); - return menutext.c_str(); - } - - int testDestroy(){ - if (animation >0) return 0; - return MTGAbility::testDestroy(); - } - - ~AManaProducer(){ - LOG("==Destroying ManaProducer Object"); - if (cost) delete cost; - SAFE_DELETE(output); - if (mParticleSys) delete mParticleSys; - LOG("==Destroying ManaProducer Object Successful!"); - } - -}; - - -/* Lifelink Ability */ -class ALifeLink:public MTGAbility{ -public: - int nbdamagesthisturn; - Damage * lastDamage; - ALifeLink(int _id, MTGCardInstance * _source):MTGAbility(_id, _source){ - nbdamagesthisturn = 0; - lastDamage = NULL; - } - - void Update(float dt){ - ActionStack * as = game->mLayers->stackLayer(); - int totaldamages = as->count(ACTION_DAMAGE,RESOLVED_OK); - if ( totaldamages > nbdamagesthisturn){ - Damage * damage = ((Damage * )as->getNext(lastDamage,ACTION_DAMAGE, RESOLVED_OK)); - while(damage){ - lastDamage = damage; - if (damage->source == source){ - source->controller()->life+= damage->damage; - } - damage = ((Damage * )as->getNext(lastDamage,ACTION_DAMAGE, RESOLVED_OK)); - } - }else if (totaldamages ==0){ - lastDamage = NULL; - } - nbdamagesthisturn = totaldamages; - } - -}; - - -//Circle of Protections -class ACircleOfProtection: public TargetAbility{ -public: - ACircleOfProtection(int _id, MTGCardInstance * source, int _color):TargetAbility(_id,source,NEW DamageTargetChooser(source,_color),NEW ManaCost(),0,0){ - cost->add(MTG_COLOR_ARTIFACT,1); - } - - int resolve(){ - Damage * damage = tc->getNextDamageTarget(); - if (!damage) return 0; - game->mLayers->stackLayer()->Fizzle(damage); - return 1; - } -}; - -//Basic regeneration mechanism for a Mana cost -class AStandardRegenerate:public ActivatedAbility{ -public: - AStandardRegenerate(int _id, MTGCardInstance * _source, MTGCardInstance * _target, ManaCost * _cost):ActivatedAbility(_id,_source,_cost,0,0){ - target = _target; - } - - int resolve(){ - MTGCardInstance * _target = (MTGCardInstance *)target; - _target->regenerate(); - PutInGraveyard * action = ((PutInGraveyard *) game->mLayers->stackLayer()->getNext(NULL,ACTION_PUTINGRAVEYARD,NOT_RESOLVED)); - while(action){ -#if defined (WIN32) || defined (LINUX) - OutputDebugString("Fizzling due to regenerate! \n"); -#endif - if (action->card == _target){ - game->mLayers->stackLayer()->Fizzle(action); - } - action = ((PutInGraveyard *) game->mLayers->stackLayer()->getNext(action,ACTION_PUTINGRAVEYARD,NOT_RESOLVED)); - } - return 1; - } - -}; - -/*Gives protection to a target */ -class AProtectionFrom:public MTGAbility{ -public: - CardDescriptor * cd; - void initProtection(){ - ((MTGCardInstance *)target)->addProtection(cd); - } - - AProtectionFrom(int _id, MTGCardInstance * _source, MTGCardInstance * _target, CardDescriptor * _cd):MTGAbility(_id, _source, _target),cd(_cd){ - initProtection(); - } - AProtectionFrom(int _id, MTGCardInstance * _source, MTGCardInstance * _target, int color):MTGAbility(_id, _source, _target){ - cd = NEW CardDescriptor(); - cd->colors[color] = 1; - initProtection(); - } - - int destroy(){ - ((MTGCardInstance *)target)->removeProtection(cd); - return 1; - } - -}; - -//Aura Enchantments that provide controller of target life or damages at a given phase of their turn -class ARegularLifeModifierAura:public MTGAbility{ -public: - int life; - int phase; - int onlyIfTargetTapped; - ARegularLifeModifierAura(int id, MTGCardInstance * _source, MTGCardInstance * _target, int _phase, int _life, int _onlyIfTargetTapped=0):MTGAbility(id,_source,_target),life(_life), phase(_phase),onlyIfTargetTapped(_onlyIfTargetTapped){ - } - - void Update(float dt){ - if (newPhase !=currentPhase && newPhase==phase && game->currentPlayer==((MTGCardInstance *)target)->controller()){ - if (!onlyIfTargetTapped || ((MTGCardInstance *)target)->tapped){ - if (life > 0){ - game->currentPlayer->life+=life; - }else{ - game->mLayers->stackLayer()->addDamage(source, game->currentPlayer, -life); - } - } - } - } -}; - - -//ExaltedAbility (Shards of Alara) -class AExalted:public ListMaintainerAbility{ -public: - int power, toughness; - MTGCardInstance * luckyWinner; - AExalted(int _id, MTGCardInstance * _source, int _power = 1, int _toughness = 1):ListMaintainerAbility(_id, _source),power(_power),toughness(_toughness){ - luckyWinner = NULL; - } - - - int canBeInList(MTGCardInstance * card){ - if (card->isAttacker() && game->currentPlayer == source->controller()) return 1; - return 0; - } - - int added(MTGCardInstance * card){ - if(cards.size() == 1){ - luckyWinner = cards.begin()->first; - luckyWinner->addToToughness(toughness); - luckyWinner->power+=power; - }else if (cards.size() == 2){ - luckyWinner->addToToughness(-toughness); - luckyWinner->power-=power; - } - return 1; - } - - int removed(MTGCardInstance * card){ - if(cards.size() == 1){ - luckyWinner = cards.begin()->first; - luckyWinner->addToToughness(toughness); - luckyWinner->power+=power; - }else if (cards.size() == 0){ - luckyWinner->addToToughness(-toughness); - luckyWinner->power-=power; - } - return 1; - } - -}; - - -//ExaltedAbility for basic abilities (Shards of Alara) -class AExaltedAbility:public ListMaintainerAbility{ -public: - int ability; - MTGCardInstance * luckyWinner; - AExaltedAbility(int _id, MTGCardInstance * _source, int _ability):ListMaintainerAbility(_id, _source),ability(_ability){ - luckyWinner = NULL; - } - - - int canBeInList(MTGCardInstance * card){ - if (card->isAttacker() && game->currentPlayer == source->controller()) return 1; - return 0; - } - - int added(MTGCardInstance * card){ - luckyWinner = cards.begin()->first; - if(cards.size() == 1){ - luckyWinner->basicAbilities[ability]+=1; - }else if (cards.size() == 2){ - luckyWinner->basicAbilities[ability]-=1; - } - return 1; - } - - int removed(MTGCardInstance * card){ - if(cards.size() == 1){ - luckyWinner->basicAbilities[ability]+=1; - }else if (cards.size() == 0){ - luckyWinner->basicAbilities[ability]-=1; - } - return 1; - } - -}; - - -//Converts lands to creatures (Kormus bell, Living lands) -class AConvertLandToCreatures:public ListMaintainerAbility{ -public: - int type; - int power, toughness; - AConvertLandToCreatures(int _id, MTGCardInstance * _source, const char * _type, int _power = 1, int _toughness = 1):ListMaintainerAbility(_id, _source),power(_power),toughness(_toughness){ - type = Subtypes::subtypesList->Add(_type); - } - - - int canBeInList(MTGCardInstance * card){ - if (card->hasType(type)) return 1; - return 0; - } - - int added(MTGCardInstance * card){ - card->power = 1; - card->setToughness(1); - card->setSubtype("creature"); - return 1; - } - - int removed(MTGCardInstance * card){ - card->removeType("creature"); - return 1; - } - -}; - -//Lords (Merfolk lord...) give power and toughness to OTHER creatures of their type, they can give them special abilities, regeneration -class ALord:public ListMaintainerAbility{ -public: - string type; - int power, toughness; - int ability; - ManaCost * regenCost; - map regenerations; - ALord(int _id, MTGCardInstance * card, const char * _type, int _power = 0 , int _toughness = 0, int _ability = -1, ManaCost * _regenCost = NULL):ListMaintainerAbility(_id,card){ - type = _type; - power = _power; - toughness = _toughness; - ability = _ability; - regenCost = _regenCost; - } - - int canBeInList(MTGCardInstance * card){ - if (card!=source && card->isACreature() && card->hasSubtype(type)) return 1; - return 0; - } - - int added(MTGCardInstance * card){ - card->power += power; - card->addToToughness(toughness); - if (ability != -1) card->basicAbilities[ability] +=1; - if (regenCost){ - AStandardRegenerate * regen = NEW AStandardRegenerate(0, card, card, regenCost); - regenerations[card] = regen; - game->addObserver(regen); - } - return 1; - } - - int removed(MTGCardInstance * card){ - card->power -= power; - card->addToToughness(-toughness); - if (ability != -1 && card->basicAbilities[ability]) card->basicAbilities[ability] -=1; - if (regenCost){ - if(regenerations.find(card) != regenerations.end()){ - if (game->isInPlay(card)) game->removeObserver(regenerations[card]); - regenerations.erase(card); - } - } - return 1; - } - -}; - -//Lords (Merfolk lord...) give power and toughness to OTHER creatures of a given color, they can give them special abilities, regeneration -class AColorLord:public ListMaintainerAbility{ -public: - int color; - int notcolor; - int power, toughness; - int ability; - ManaCost * regenCost; - map regenerations; - AColorLord(int _id, MTGCardInstance * card, int _color, int _notcolor = -1, int _power = 0 , int _toughness = 0, int _ability = -1, ManaCost * _regenCost = NULL):ListMaintainerAbility(_id,card){ - color = _color; - notcolor = _notcolor; - power = _power; - toughness = _toughness; - ability = _ability; - regenCost = _regenCost; - } - - int canBeInList(MTGCardInstance * card){ - if (notcolor > -1){ - if (card!=source && card->isACreature() && !card->hasColor(color)) return 1; - }else{ - if (card!=source && card->isACreature() && card->hasColor(color)) return 1; - } - return 0; - } - - int added(MTGCardInstance * card){ - card->power += power; - card->addToToughness(toughness); - if (ability != -1) card->basicAbilities[ability] +=1; - if (regenCost){ - AStandardRegenerate * regen = NEW AStandardRegenerate(0, card, card, regenCost); - regenerations[card] = regen; - game->addObserver(regen); - } - return 1; - } - - int removed(MTGCardInstance * card){ - card->power -= power; - card->addToToughness(-toughness); - if (ability != -1 && card->basicAbilities[ability]) card->basicAbilities[ability] -=1; - if (regenCost){ - if(regenerations.find(card) != regenerations.end()){ - game->removeObserver(regenerations[card]); - regenerations.erase(card); - } - } - return 1; - } - -}; - - -/* Standard Damager, can choose a NEW target each time the price is paid */ -class ADamager:public TargetAbility{ -public: - int damage; - ADamager(int id, MTGCardInstance * card, ManaCost * _cost, int _damage, TargetChooser * _tc = NULL, int _tap = 1):TargetAbility(id,card, _tc, _cost,0,_tap),damage(_damage){ - if (!tc) tc = NEW DamageableTargetChooser(card); - } - int resolve(){ - Damageable * _target = tc->getNextDamageableTarget(); - GameObserver::GetInstance()->mLayers->stackLayer()->addDamage(source,_target, damage); - return 1; - } - - -}; - -/* Can tap a target for a cost */ -class ATapper:public TargetAbility{ -public: - int damage; - ATapper(int id, MTGCardInstance * card, ManaCost * _cost, TargetChooser * _chooser):TargetAbility(id,card, _chooser, _cost){ - } - - int resolve(){ - MTGCardInstance * _target = tc->getNextCardTarget(); - if (_target){ - _target->tapped = true; - } - return 1; - } - -}; - -// Add life of gives damage if a given zone has more or less than [condition] cards at the beginning of [phase] -//Ex : the rack, ivory tower... -class ALifeZoneLink:public MTGAbility{ -public: - int phase; - int condition; - int life; - int controller; - int nbcards; - MTGGameZone * zone; - ALifeZoneLink(int _id ,MTGCardInstance * card, int _phase, int _condition, int _life = -1, int _controller = 0, MTGGameZone * _zone = NULL):MTGAbility(_id, card){ - phase = _phase; - condition = _condition; - controller = _controller; - life = _life; - zone = _zone; - if (zone == NULL){ - if (controller){ - zone = game->currentPlayer->game->hand; - }else{ - zone = game->opponent()->game->hand; - } - } - } - - void Update(float dt){ - if (newPhase != currentPhase && newPhase == phase){ - if ((controller && game->currentPlayer == source->controller()) ||(!controller && game->currentPlayer != source->controller()) ){ - if ((condition < 0 && zone->nb_cards < - condition) ||(condition >0 && zone->nb_cards > condition)){ - int diff = zone->nb_cards - condition; - if (condition < 0) diff = - condition - zone->nb_cards; - if (life > 0){ - game->currentPlayer->life+=life*diff; - }else{ - game->mLayers->stackLayer()->addDamage(source,game->currentPlayer,-life*diff); - } - } - } - } - } -}; - -//Creatures that cannot attack if opponent has not a given type of land, and die if controller has not this type of land -//Ex : pirate ship... -class AStrongLandLinkCreature: public MTGAbility{ -public: - char land[20]; - AStrongLandLinkCreature(int _id, MTGCardInstance * _source, const char * _land):MTGAbility(_id, _source){ - sprintf(land,"%s",_land); - } - - void Update(float dt){ - if (source->isAttacker()){ - if (!game->opponent()->game->inPlay->hasType(land)){ - source->attacker=0; - source->tapped = 0; - //TODO Improve, there can be race conditions here - } - } - Player * player = source->controller(); - if(!player->game->inPlay->hasType(land)){ - player->game->putInGraveyard(source); - } - } -}; - -//Steal control of a target -class AControlStealAura: public MTGAbility{ -public: - Player * originalController; - AControlStealAura(int _id , MTGCardInstance * _source, MTGCardInstance * _target):MTGAbility(_id, _source, _target){ - originalController = _target->controller(); - _target->changeController(game->currentlyActing()); - } - - int destroy(){ - MTGCardInstance * _target = (MTGCardInstance *) target; - if (_target->controller()->game->inPlay->hasCard(_target)){ //if the target is still in game -> spell was destroyed - _target->changeController(originalController); - } - return 1; - } - //TODO put it back into owners's graveyard if needed... -}; - -//Ability to untap a target -class AUntaper:public TargetAbility{ -public: - AUntaper(int _id, MTGCardInstance * card, ManaCost * _manacost, TargetChooser * _tc):TargetAbility(_id,card,_tc,_manacost){ - } - - int resolve(){ - tc->getNextCardTarget()->tapped = 0; - return 1; - } - -}; - - -//Same as StealControl Aura ???? Obsolete ? -class ATakeControlAura:public MTGAbility{ -public: - Player * previousController; - ATakeControlAura(int _id, MTGCardInstance * _source, MTGCardInstance * _target):MTGAbility(_id, _source,_target){ - previousController = _target->controller(); - previousController->game->putInZone(_target, previousController->game->inPlay, source->controller()->game->inPlay); - - } - - int destroy(){ - MTGCardInstance * _target = (MTGCardInstance *) target; - if (_target->controller()->game->inPlay->hasCard(_target)){ - _target->controller()->game->putInZone(_target, _target->controller()->game->inPlay, previousController->game->inPlay); - } - return 1; - } - -}; - -//Creatures that kill their blockers -//Ex : Cockatrice -class AOldSchoolDeathtouch:public MTGAbility{ -public: - MTGCardInstance * opponents[20]; - int nbOpponents; - AOldSchoolDeathtouch(int _id, MTGCardInstance * _source):MTGAbility(_id, _source){ - nbOpponents = 0; - } - - void Update(float dt){ - if (newPhase != currentPhase){ - if( newPhase == MTG_PHASE_COMBATDAMAGE){ - nbOpponents = 0; - MTGCardInstance * opponent = source->getNextOpponent(); - while (opponent && !opponent->hasSubtype("wall")){ - opponents[nbOpponents] = opponent; - nbOpponents ++; - opponent = source->getNextOpponent(opponent); - } - }else if (newPhase == MTG_PHASE_COMBATEND){ - for (int i = 0; i < nbOpponents ; i++){ - game->mLayers->stackLayer()->addPutInGraveyard(opponents[i]); - } - } - } - } - - int testDestroy(){ - if(!game->isInPlay(source) && currentPhase != MTG_PHASE_UNTAP){ - return 0; - }else{ - return MTGAbility::testDestroy(); - } - } -}; - - -//Converts a card to a creature (Aura) -class AConvertToCreatureAura:public MTGAbility{ -public: - AConvertToCreatureAura(int _id, MTGCardInstance * _source, MTGCardInstance * _target, int _power, int _toughness):MTGAbility(_id, _source, _target){ - _target->setSubtype("creature"); - _target->power = _power; - _target->toughness = _toughness; - _target->life = _toughness; - //_target->afterDamage(); - _target->doDamageTest = 1; - } - - int destroy(){ - MTGCardInstance * _target = (MTGCardInstance *) target; - _target->removeType("creature"); - return 1; - } -}; - -/* -Specific Classes -*/ - -// 1092 Specific to Aladdin's Lamp -class AAladdinsLamp: public TargetAbility{ - public: - CardDisplay cd; - int nbcards; - int init; - AAladdinsLamp(int _id, MTGCardInstance * card):TargetAbility(_id,card){ - cost = NEW ManaCost(); - cost->x(); - cd = CardDisplay(1,game,SCREEN_WIDTH/2, SCREEN_HEIGHT/2,NULL); - MTGGameZone * zones[] = {game->currentPlayer->game->library}; - tc = NEW TargetZoneChooser(zones,1,source); - nbcards = 0; - init = 0; - } - - void Update(float dt){ - if (waitingForAnswer){ - if (!init){ - cd.resetObjects(); - int wished = game->currentlyActing()->getManaPool()->getConvertedCost(); - game->currentlyActing()->getManaPool()->pay(cost); - nbcards = 0; - MTGGameZone * library = game->currentlyActing()->game->library; - while (nbcards < wished && nbcards < library->nb_cards){ - cd.AddCard(library->cards[library->nb_cards - 1 - nbcards]); - nbcards++; - } - init = 1; - } - cd.Update(dt); - cd.CheckUserInput(dt); - } - } - - void Render(float dt){ - if (waitingForAnswer){ - cd.Render(); - } - } - - - int fireAbility(){ - source->tapped = 1; - MTGLibrary * library = game->currentlyActing()->game->library; - library->removeCard(tc->getNextCardTarget()); - library->shuffleTopToBottom(nbcards - 1 ); - library->addCard(tc->getNextCardTarget()); - init = 0; - return 1; - } - - int resolve(){return 1;}; - - -}; - - - - -//Ankh of Mishra -class AAnkhOfMishra: public MTGAbility{ -public: - int playerLands[2]; - AAnkhOfMishra(int id, MTGCardInstance * _source):MTGAbility(id, _source){ - for (int i=0; i< 2; i++){ - playerLands[i] = GameObserver::GetInstance()->players[i]->game->inPlay->countByType("land"); - } - } - - void Update(float dt){ - for (int i=0; i < 2; i++){ - int lands = GameObserver::GetInstance()->players[i]->game->inPlay->countByType("land"); - while (lands > playerLands[i]){ - GameObserver::GetInstance()->mLayers->stackLayer()->addDamage(source,GameObserver::GetInstance()->players[i], 2); - playerLands[i]++; - } - } - } -}; - - - -// Armageddon Clock -class AArmageddonClock:public MTGAbility{ -public: - int counters; - ManaCost cost; - AArmageddonClock(int id, MTGCardInstance * _source):MTGAbility(id, _source){ - counters = 0; - int _cost[] = {MTG_COLOR_ARTIFACT, 4}; - cost = ManaCost(_cost,1); - } - - void Update(float dt){ - if (newPhase != currentPhase){ - if (newPhase == MTG_PHASE_UPKEEP && game->currentPlayer->game->inPlay->hasCard(source)){ - counters ++; - }else if (newPhase == MTG_PHASE_DRAW && counters > 0 && game->currentPlayer->game->inPlay->hasCard(source)){ //End of upkeep = beginning of draw - GameObserver::GetInstance()->mLayers->stackLayer()->addDamage(source,GameObserver::GetInstance()->players[0], counters); - GameObserver::GetInstance()->mLayers->stackLayer()->addDamage(source,GameObserver::GetInstance()->players[1], counters); - } - } - } - int isReactingToClick(MTGCardInstance * _card){ - if (counters > 0 && _card == source && currentPhase == MTG_PHASE_UPKEEP){ - if (game->currentlyActing()->getManaPool()->canAfford( & cost)){ - return 1; - } - } - return 0; - } - - int reactToClick(MTGCardInstance * _card){ - if (!isReactingToClick( _card)) return 0; - game->currentlyActing()->getManaPool()->pay(& cost); - counters --; - return 1; - } -}; - - -//Black Vise -class ABlackVise: public MTGAbility{ -public: - int nbcards; - ABlackVise(int id, MTGCardInstance * _source):MTGAbility(id, _source){ - nbcards = game->opponent()->game->hand->nb_cards; - } - - void Update(float dt){ - if (newPhase == MTG_PHASE_UPKEEP && GameObserver::GetInstance()->opponent()->game->inPlay->hasCard(source)){ - nbcards = game->currentPlayer->game->hand->nb_cards; - } - if (newPhase != currentPhase && newPhase == MTG_PHASE_DRAW && GameObserver::GetInstance()->opponent()->game->inPlay->hasCard(source)){ - if ( nbcards > 4) game->mLayers->stackLayer()->addDamage(source,game->currentPlayer, nbcards - 4); - } - } -}; - - -//Channel -class AChannel:public ActivatedAbility{ -public: - - AChannel(int _id, MTGCardInstance * card):ActivatedAbility(_id, card,0,0,0){ - } - - int isReactingToClick(PlayGuiObject * object){ - if (object->type == GUI_AVATAR){ - Player * player = ((GuiAvatar *)object)->player; - if (player == source->controller()) return 1; - } - return 0; - } - - int resolve(){ - source->controller()->life--; - source->controller()->getManaPool()->add(MTG_COLOR_ARTIFACT, 1); - return 1; - } - - int testDestroy(){ - if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP) return 1; - currentPhase = newPhase; - return 0; - } -}; - - -// Clockwork Beast -class AClockworkBeast:public MTGAbility{ -public: - int counters; - ManaCost cost; - AClockworkBeast(int id, MTGCardInstance * _source):MTGAbility(id, _source){ - counters = 7; - ((MTGCardInstance *)target)->power+=7; - int _cost[] = {MTG_COLOR_ARTIFACT, 1}; - cost = ManaCost(_cost,1); - } - - void Update(float dt){ - if (newPhase != currentPhase && newPhase == MTG_PHASE_COMBATEND){ - if (((MTGCardInstance *)source)->isAttacker() || ((MTGCardInstance *)source)->isDefenser()){ - counters--; - ((MTGCardInstance *)target)->power-=1; - } - } - } - int isReactingToClick(MTGCardInstance * _card){ - if (counters < 7 && _card == source && currentPhase == MTG_PHASE_UPKEEP && game->currentPlayer->game->inPlay->hasCard(source)){ - if (game->currentlyActing()->getManaPool()->canAfford( & cost)){ - return 1; - } - } - return 0; - } - - int reactToClick(MTGCardInstance * _card){ - if (!isReactingToClick( _card)) return 0; - game->currentlyActing()->getManaPool()->pay(& cost); - counters ++; - ((MTGCardInstance *)target)->power++; - ((MTGCardInstance *)target)->tapped = 1; - return 1; - } -}; - -//1102: Conservator -class AConservator: public MTGAbility{ -public: - int canprevent; - ManaCost cost; - AConservator(int _id, MTGCardInstance * _source):MTGAbility(_id, _source){ - canprevent = 0; - int _cost[] = {MTG_COLOR_ARTIFACT, 2}; - cost = ManaCost(_cost, 1); - } - - int alterDamage(Damage * damage){ - if (canprevent && damage->target == source->controller()){ - if (damage->damage >= canprevent){ - damage->damage-=canprevent; - canprevent = 0; - }else{ - canprevent-=damage->damage; - damage->damage = 0; - } - } - return 1; - } - int alterDamage(){ - if (canprevent){ - ActionStack * stack = game->mLayers->stackLayer(); - for (int i = stack->mCount-1; i>=0; i--){ - if (!canprevent) return 1; - Interruptible * current = ((Interruptible *)stack->mObjects[i]); - if (current->type == ACTION_DAMAGE && current->state==NOT_RESOLVED){ - Damage * damage = (Damage *)current; - alterDamage(damage); - }else if (current->type == ACTION_DAMAGES && current->state == NOT_RESOLVED){ - DamageStack * damages = (DamageStack *)current; - for (int j = damages->mCount-1;j >=0; j--){ - alterDamage(((Damage *)damages->mObjects[j])); - } - } - } - } - return 1; - } - - void Update(float dt){ - alterDamage(); - } - - int isReactingToClick(MTGCardInstance * _card){ - if ( _card == source && game->currentlyActing()->game->inPlay->hasCard(source) && !_card->isTapped()){ - if (game->currentlyActing()->getManaPool()->canAfford( & cost)){ - return 1; - } - } - return 0; - } - - int reactToClick(MTGCardInstance * _card){ - if (!isReactingToClick( _card)) return 0; - game->currentlyActing()->getManaPool()->pay(& cost); - source->tapped = 1; - canprevent = 2; - alterDamage(); - return 1; - } - -}; - - -//Creature bond -class ACreatureBond:public TriggeredAbility{ -public: - int resolved; - ACreatureBond(int _id, MTGCardInstance * _source, MTGCardInstance * _target):TriggeredAbility(_id,_source,_target){ - resolved = 1; - } - - int trigger(){ - MTGCardInstance * _target = (MTGCardInstance *) target; - for (int i = 0; i < 2; i++){ - if (game->players[i]->game->graveyard->hasCard(_target)) return 1; - } - return 0; - } - - int resolve(){ - MTGCardInstance * _target = (MTGCardInstance *) target; - game->mLayers->stackLayer()->addDamage(source,_target->controller(),_target->toughness); - resolved = 1; - return 1; - } - - int testDestroy(){ - MTGCardInstance * _target = (MTGCardInstance *)target; - if(_target->controller()->game->graveyard->hasCard(_target) && !resolved){ - return 0; - }else{ - return TriggeredAbility::testDestroy(); - } - } -}; - -//1105: Dingus Egg -class ADingusEgg: public MTGAbility{ -public: - int playerLands[2]; - ADingusEgg(int id, MTGCardInstance * _source):MTGAbility(id, _source){ - for (int i=0; i< 2; i++){ - playerLands[i] = GameObserver::GetInstance()->players[i]->game->inPlay->countByType("land"); - } - } - - void Update(float dt){ - for (int i=0; i < 2; i++){ - int lands = GameObserver::GetInstance()->players[i]->game->inPlay->countByType("land"); - while (lands < playerLands[i]){ - GameObserver::GetInstance()->mLayers->stackLayer()->addDamage(source,GameObserver::GetInstance()->players[i], 2); - playerLands[i]--; - } - } - } -}; - - - -//1106 DisruptingScepter -class ADisruptingScepter:public TargetAbility{ -public: - ADisruptingScepter(int id, MTGCardInstance * _source):TargetAbility(id,_source){ - MTGGameZone * zones[] = {GameObserver::GetInstance()->opponent()->game->hand}; - tc = NEW TargetZoneChooser(zones,1,_source); - int _cost[] = {MTG_COLOR_ARTIFACT, 3}; - cost = NEW ManaCost(_cost,1); - } - - void Update(float dt){ - if (game->opponent()->isAI()){ - if(waitingForAnswer){ - MTGCardInstance * card = ((AIPlayer *)game->opponent())->chooseCard(tc, source); - if (card) tc->toggleTarget(card); - if (!card || tc->targetsReadyCheck() == TARGET_OK) waitingForAnswer = 0; - } - TargetAbility::Update(dt); - }else{ - TargetAbility::Update(dt); - } - } - - int resolve(){ - game->opponent()->game->putInGraveyard(tc->getNextCardTarget()); - return 1; - } - - -}; - - -//1108 Ebony Horse -class AEbonyHorse:public TargetAbility{ -public: - - AEbonyHorse(int _id, MTGCardInstance * _source):TargetAbility(_id,_source, NEW CreatureTargetChooser()){ - int _cost[] = {MTG_COLOR_ARTIFACT, 2}; - cost = NEW ManaCost(_cost,1); - } - - int resolve(){ - tc->getNextCardTarget()->attacker = 0; - return 1; - } - -}; - -//1345 Farmstead -class AFarmstead:public ActivatedAbility{ -public: - AFarmstead(int _id, MTGCardInstance * source, MTGCardInstance * _target):ActivatedAbility(_id, source,0,1,0){ - int _cost[] = {MTG_COLOR_WHITE, 2}; - cost = NEW ManaCost(_cost,1); - target = _target; - } - - int isReactingToClick(MTGCardInstance * card){ - if (!ActivatedAbility::isReactingToClick(card)) return 0; - if (currentPhase == MTG_PHASE_UPKEEP) return 1; - return 0; - } - - int resolve(){ - source->controller()->life++; - return 1; - } - -}; - -//1110 Glasses of Urza -class AGlassesOfUrza:public MTGAbility{ -public: - CardDisplay * display; - AGlassesOfUrza(int _id, MTGCardInstance * _source):MTGAbility(_id, _source){ - display = NEW CardDisplay(0, game,SCREEN_WIDTH/2, SCREEN_HEIGHT/2,NULL); - } - - void Update(float dt){ - if(modal){ - display->Update(dt); - } - } - - void CheckUserInput(float dt){ - if (modal){ - display->CheckUserInput(dt); - JGE * mEngine = JGE::GetInstance(); - if (mEngine->GetButtonClick(PSP_CTRL_CROSS)){ - modal = 0; - } - } - } - - void Render(float dt){ - if (modal){ - display->Render(); - } - - } - int isReactingToClick(MTGCardInstance * card){ - if ( card == source){ - if (game->currentlyActing()->game->isInPlay(card) && !source->isTapped()){ - return 1; - } - } - return 0; - } - - int reactToClick(MTGCardInstance * card){ - if (!isReactingToClick(card)) return 0; - source->tapped = 1; - modal = 1; - return 1; - } - -}; - -//1112 Howling Mine -class AHowlingMine:public MTGAbility{ -public: - AHowlingMine(int _id, MTGCardInstance * _source):MTGAbility(_id, _source){} - - void Update(float dt){ - if (newPhase != currentPhase && newPhase == MTG_PHASE_DRAW && !source->tapped){ - game->mLayers->stackLayer()->addDraw(game->currentPlayer); - } - } -}; - -//1119 Jayemdae Tome -class AJayemdaeTome:public ActivatedAbility{ -public: - AJayemdaeTome(int _id, MTGCardInstance * card):ActivatedAbility(_id, card){ - int _cost[] = {MTG_COLOR_ARTIFACT, 4}; - cost = NEW ManaCost(_cost,1); - } - - int resolve(){ - game->mLayers->stackLayer()->addDraw(source->controller()); - return 1; - } -}; - - -//Living Artifact -class ALivingArtifact:public MTGAbility{ -public: - int usedThisTurn; - int counters; - Damage * latest; - ALivingArtifact(int _id, MTGCardInstance * _source, MTGCardInstance * _target):MTGAbility(_id,_source,_target){ - usedThisTurn = 0; - counters = 0; - latest = NULL; - } - - void Update(float dt){ - if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP) usedThisTurn = 0; - Damage * damage = ((Damage *)game->mLayers->stackLayer()->getNext(latest,ACTION_DAMAGE,RESOLVED_OK)); - while (damage){ - if (damage->target == source->controller()){ - counters += damage->damage; - } - latest = damage; - damage = ((Damage *)game->mLayers->stackLayer()->getNext(damage,ACTION_DAMAGE,RESOLVED_OK)); - } - } - - int isReactingtoclick(MTGCardInstance * card){ - if (currentPhase == MTG_PHASE_UPKEEP && card == source && game->currentPlayer == source->controller() && counters && !usedThisTurn){ - return 1; - } - return 0; - } - - int reactToClick(MTGCardInstance * card){ - source->controller()->life+=1; - counters--; - usedThisTurn = 1; - return 1; - } - -}; - -//Lord of the Pit -class ALordOfThePit: public TargetAbility{ -public: - int paidThisTurn; - ALordOfThePit(int _id, MTGCardInstance * source):TargetAbility(_id, source, NEW CreatureTargetChooser(),0,1,0){ - paidThisTurn = 1; - } - - void Update(float dt){ - if (newPhase != currentPhase && source->controller() == game->currentPlayer){ - if (newPhase == MTG_PHASE_UNTAP){ - paidThisTurn = 0; - }else if( newPhase == MTG_PHASE_UPKEEP + 1 && !paidThisTurn){ - game->mLayers->stackLayer()->addDamage(source,source->controller(), 7); - } - } - TargetAbility::Update(dt); - } - - int isReactingToClick(MTGCardInstance * card){ - if (currentPhase != MTG_PHASE_UPKEEP || paidThisTurn) return 0; - return TargetAbility::isReactingToClick(card); - } - - int resolve(){ - MTGCardInstance * card = tc->getNextCardTarget(); - if (card && card != source && card->controller() == source->controller()){ - card->controller()->game->putInGraveyard(card); - paidThisTurn = 1; - return 1; - } - return 0; - } - -}; -//1143 Animate Dead -class AAnimateDead:public MTGAbility{ -public: - AAnimateDead(int _id, MTGCardInstance * _source, MTGCardInstance * _target):MTGAbility(_id, _source, _target){ - MTGCardInstance * card = _target; - card->power--; - card->life = card->toughness; - //Put the card in play again, with all its abilities ! - //AbilityFactory af; - Spell * spell = NEW Spell(card); - //af.addAbilities(game->mLayers->actionLayer()->getMaxId(), spell); - source->controller()->game->putInZone(card, _target->controller()->game->graveyard, source->controller()->game->stack); - spell->resolve(); - delete spell; - } - - int destroy(){ - MTGCardInstance * card = (MTGCardInstance *) target; - card->power++; - return 1; - } -}; - -//1144 Bad Moon, 1341 Crusade -class ABadMoon:public ListMaintainerAbility{ -public: - int color; - ABadMoon(int _id, MTGCardInstance * _source, int _color = MTG_COLOR_BLACK):ListMaintainerAbility(_id, _source),color(_color){ - } - - int canBeInList(MTGCardInstance * card){ - if (card->isACreature() && card->hasColor(color)) return 1; - return 0; - } - - int added(MTGCardInstance * card){ - card->power += 1; - card->addToToughness(1); - return 1; - } - - int removed(MTGCardInstance * card){ - card->power -= 1; - card->addToToughness(-1); - return 1; - } - -}; - - -//1159 Erg Raiders -class AErgRaiders:public MTGAbility{ -public: - int init; - int dealDamage; - AErgRaiders(int _id, MTGCardInstance * _source):MTGAbility(_id, _source){ - init = 0; - dealDamage = 0; - } - - void Update(float dt){ - if (newPhase != currentPhase){ - Player * controller = source->controller(); - if (newPhase == MTG_PHASE_COMBATDAMAGE && game->currentPlayer == controller){ - if (!source->isAttacker() && init){ - dealDamage = 1; - } - }else if (newPhase == MTG_PHASE_UNTAP && game->currentPlayer != controller){ - if (dealDamage){ - game->mLayers->stackLayer()->addDamage(source, controller,2); - } - init = 1; - dealDamage = 0; - } - } - - } -}; - -//Fastbond -class AFastbond:public TriggeredAbility{ -public: - int alreadyPlayedALand; - AFastbond(int _id, MTGCardInstance * card):TriggeredAbility(_id, card){ - alreadyPlayedALand = 0; - } - - void Update(float dt){ - if (newPhase!=currentPhase && newPhase == MTG_PHASE_UNTAP){ - alreadyPlayedALand = 0; - } - TriggeredAbility::Update(dt); - } - - int trigger(){ - if(source->controller()->canPutLandsIntoPlay==0) return 1; - return 0; - } - - int resolve(){ - source->controller()->canPutLandsIntoPlay = 1; - if (alreadyPlayedALand){ - game->mLayers->stackLayer()->addDamage(source, source->controller(), 1); - } - alreadyPlayedALand = 1; - return 1; - } -}; - - - -//1165 Hypnotic Specter -class AHypnoticSpecter:public MTGAbility{ -public: - int nbdamagesthisturn[2]; - AHypnoticSpecter(int _id, MTGCardInstance * _source):MTGAbility(_id, _source){ - currentPhase = -1; - for (int i = 0; i < 2; i++){ - nbdamagesthisturn[i] = 0; - } - } - - void Update(float dt){ - if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP){ - for (int i = 0; i < 2; i++){ - nbdamagesthisturn[i] = 0; - } - } - - ActionStack * as = game->mLayers->stackLayer(); - int nbdamages[2]; - for (int i = 0; i < 2; i++){ - nbdamages[i] = 0; - } - - Damage * current = ((Damage *)as->getNext(NULL,ACTION_DAMAGE,RESOLVED_OK)); - while(current){ - if (current->source == source){ - for (int j=0; j < 2; j++){ - if(current->target == game->players[j]) nbdamages[j]++; - } - } - current = ((Damage *)as->getNext(current,ACTION_DAMAGE,RESOLVED_OK)); - - } - - for (int i = 0; i < 2; i++){ - while(nbdamages[i] > nbdamagesthisturn[i]){ - nbdamagesthisturn[i]++; - game->players[i]->game->discardRandom(game->players[i]->game->hand); - } - } - - - } - -}; - -//1117 Jandor's Ring -class AJandorsRing:public ActivatedAbility{ -public: - AJandorsRing(int _id, MTGCardInstance * _source):ActivatedAbility(_id,_source, NEW ManaCost()){ - cost->add(MTG_COLOR_ARTIFACT, 2); - } - - int isReactingToClick(MTGCardInstance * card){ - if (!source->controller()->game->hand->hasCard(source->controller()->game->library->lastCardDrawn)) return 0; - return ActivatedAbility::isReactingToClick(card); - } - - int resolve(){ - source->controller()->game->putInGraveyard(source->controller()->game->library->lastCardDrawn); - game->mLayers->stackLayer()->addDraw(source->controller()); - return 1; - } - -}; - - -//Kudzu. -//What happens when there are no targets ??? -class AKudzu: public TargetAbility{ -public: - int previouslyTapped; - AKudzu(int _id, MTGCardInstance * card, MTGCardInstance * _target):TargetAbility(_id,card, NEW TypeTargetChooser("land",card)){ - tc->toggleTarget(_target); - target = _target; - previouslyTapped = 0; - if (_target->tapped) previouslyTapped = 1; - } - - - void Update(float dt){ - MTGCardInstance * _target = (MTGCardInstance *)target; - if (!_target->tapped){ - previouslyTapped = 0; - }else if (!previouslyTapped){ -#if defined (WIN32) || defined (LINUX) - OutputDebugString("Kudzu Strikes !\n"); -#endif - MTGCardInstance * _target = (MTGCardInstance *)target; - _target->controller()->game->putInGraveyard(_target); - reactToClick(source); // ???? - } - TargetAbility::Update(dt); - } - - int isReactingToClick(MTGCardInstance * card){ - MTGCardInstance * _target = (MTGCardInstance *)target; - if (card == source && (!_target || !_target->isInPlay())){ -#if defined (WIN32) || defined (LINUX) - OutputDebugString("Kudzu Reacts to click !\n"); -#endif - return 1; - } - return 0; - } - -/* - int reactToClick(MTGCardInstance * card){ - if (!waitingForAnswer) { - }else{ - tc->toggleTarget(card); - } - return 1; - } - */ - - int resolve(){ - target = tc->getNextCardTarget(); - source->target = (MTGCardInstance *) target; - previouslyTapped = 0; - if (source->target->tapped) previouslyTapped = 1; - return 1; - } - - int testDestroy(){ - GameObserver * g = GameObserver::GetInstance(); - int stillLandsInPlay = 0; - for (int i = 0; i < 2; i++){ - if (game->players[i]->game->inPlay->hasType("land")) stillLandsInPlay = 1; - } - if (!stillLandsInPlay){ - source->controller()->game->putInGraveyard(source); - return 1; - } - - if (!game->isInPlay(source)){ - return 1; - } - - return 0; - } - - -}; - -//Millstone -class AMillstone:public TargetAbility{ -public: - AMillstone(int _id, MTGCardInstance * card):TargetAbility(_id,card, NEW PlayerTargetChooser(), NEW ManaCost()){ - cost->add(MTG_COLOR_ARTIFACT, 2); - } - - int resolve(){ - Player * player = tc->getNextPlayerTarget(); - if (!player) return 0; - MTGLibrary * library = player->game->library; - for (int i = 0; i < 2; i++){ - if (library->nb_cards) - player->game->putInZone(library->cards[library->nb_cards-1],library, player->game->graveyard); - } - return 1; - } - -}; - -//1170: Nightmare -class ANightmare:public ListMaintainerAbility{ -public: - ANightmare(int _id, MTGCardInstance * _source):ListMaintainerAbility(_id, _source){ - } - - int canBeInList(MTGCardInstance * card){ - if (source->controller()->game->inPlay->hasCard(card) && card->hasType("swamp") ) return 1; - return 0; - } - - int added(MTGCardInstance * card){ - source->power += 1; - source->addToToughness(1); - return 1; - } - - int removed(MTGCardInstance * card){ - source->power -= 1; - source->addToToughness(-1); - return 1; - } - -}; - - - -//1172 Pestilence -class APestilence: public ActivatedAbility{ -public: - APestilence(int _id, MTGCardInstance * card):ActivatedAbility(_id, card, NEW ManaCost(), 0,0){ - cost->add(MTG_COLOR_BLACK, 1); - } - - void Update(float dt){ - if (newPhase !=currentPhase && newPhase == MTG_PHASE_EOT){ - if (!game->players[0]->game->inPlay->hasType("creature") && !game->players[1]->game->inPlay->hasType("creature")){ - source->controller()->game->putInGraveyard(source); - } - } - } - - int resolve(){ - for (int i = 0; i < 2 ; i++){ - MTGInPlay * inplay = game->players[i]->game->inPlay; - for (int j = inplay->nb_cards - 1 ; j >=0; j--){ - if (inplay->cards[j]->isACreature()) game->mLayers->stackLayer()->addDamage(source,inplay->cards[j],1); - } - game->mLayers->stackLayer()->addDamage(source,game->players[i],1); - } - return 1; - } - -}; - -//Plague Rats and similar. Power and toughness equal to number of cards that share a name -class APlagueRats:public ListMaintainerAbility{ -public: - string name; - APlagueRats(int _id, MTGCardInstance * _source, const char * _name):ListMaintainerAbility(_id,_source){ - name = _name; - std::transform(name.begin(), name.end(), name.begin(),::tolower ); - } - - int canBeInList(MTGCardInstance * card){ - if (card == source) return 0; - string compared = card->name; - std::transform( compared.begin(), compared.end(), compared.begin(),::tolower ); - if (name.compare(compared) == 0) return 1; - return 0; - } - - int added(MTGCardInstance * card){ - source->power += 1; - source->addToToughness(1); - return 1; - } - - int removed(MTGCardInstance * card){ - source->power -= 1; - source->addToToughness(-1); - return 1; - } - -}; - -//Power Leak -class APowerLeak:public TriggeredAbility{ -public: - int damagesToDealThisTurn; - ManaCost cost; - APowerLeak(int _id, MTGCardInstance * _source, MTGCardInstance * _target):TriggeredAbility(_id, _source, _target){ - cost.add(MTG_COLOR_ARTIFACT, 1); - damagesToDealThisTurn = 0; - } - - void Update(float dt){ - MTGCardInstance * _target = (MTGCardInstance *) target; - if (newPhase != currentPhase && newPhase == MTG_PHASE_UPKEEP && _target->controller() == game->currentPlayer){ - damagesToDealThisTurn = 2; - } - TriggeredAbility::Update(dt); - } - - int isReactingToClick(MTGCardInstance * card){ - MTGCardInstance * _target = (MTGCardInstance *) target; - if (damagesToDealThisTurn && currentPhase == MTG_PHASE_UPKEEP && card==source && _target->controller() == game->currentPlayer){ - if (game->currentPlayer->getManaPool()->canAfford(& cost)) return 1; - } - return 0; - } - - int reactToclick(MTGCardInstance * card){ - game->currentPlayer->getManaPool()->pay( & cost); - damagesToDealThisTurn--; - return 1; - } - - int trigger(){ - MTGCardInstance * _target = (MTGCardInstance *) target; - if (newPhase != currentPhase && newPhase == MTG_PHASE_DRAW && _target->controller() == game->currentPlayer){ - if (damagesToDealThisTurn) return 1; - } - return 0; - } - - int resolve(){ - MTGCardInstance * _target = (MTGCardInstance *) target; - game->mLayers->stackLayer()->addDamage(source,_target->controller(), damagesToDealThisTurn); - return 1; - } -}; - -//Power Surge -class APowerSurge:public TriggeredAbility{ -public: - int totalLands; - APowerSurge(int _id, MTGCardInstance * _source):TriggeredAbility(_id,_source){ - totalLands = 0; - } - - int trigger(){ - if (newPhase != currentPhase && newPhase == MTG_PHASE_EOT){ - //That's ugly but untapped land at the beginning of the turn are opponent's untapped lands at the end of the turn - totalLands = 0; - MTGInPlay * inPlay = game->opponent()->game->inPlay; - for (int i = 0; i < inPlay->nb_cards; i++){ - MTGCardInstance * card = inPlay->cards[i]; - if (!card->tapped && card->hasType("land")){ - totalLands++; - } - } - } - if (newPhase != currentPhase && newPhase == MTG_PHASE_UPKEEP && totalLands){ - return 1; - } - return 0; - } - - int resolve(){ - if (totalLands) game->mLayers->stackLayer()->addDamage(source,game->currentPlayer,totalLands); - totalLands = 0; - return 1; - } -}; - -//1175 Royal Assassin -class ARoyalAssassin:public TargetAbility{ -public: - - ARoyalAssassin(int _id, MTGCardInstance * _source):TargetAbility(_id,_source, NEW CreatureTargetChooser()){ - } - - int resolve(){ - MTGCardInstance * _target = tc->getNextCardTarget(); - if(_target && _target->tapped){ - _target->controller()->game->putInGraveyard(_target); - return 1; - } - return 0; - } - -}; - - -//1176 Sacrifice -class ASacrifice:public InstantAbility{ -public: - ASacrifice(int _id, MTGCardInstance * _source, MTGCardInstance * _target):InstantAbility(_id, _source){ - target = _target; - } - - int resolve(){ - MTGCardInstance * _target = (MTGCardInstance *) target; - if (_target->isInPlay()){ - game->currentlyActing()->game->putInGraveyard(_target); - int x = _target->getManaCost()->getConvertedCost(); - game->currentlyActing()->getManaPool()->add(MTG_COLOR_BLACK, x); - } - return 1; - } - -}; - -//1178 Scavenging Ghoul -class AScavengingGhoul:public MTGAbility{ -public: - int counters; - AScavengingGhoul(int _id, MTGCardInstance * _source, MTGCardInstance * _target):MTGAbility(_id, _source, _target){ - counters = 0; - } - - - void Update(float dt){ - //TODO - } - - int isReactingToClick(MTGCardInstance * _card){ - if (counters > 0 && _card == source && game->currentlyActing()->game->inPlay->hasCard(source)){ - return 1; - } - return 0; - } - - int reactToClick(MTGCardInstance * _card){ - if (!isReactingToClick( _card)) return 0; - counters--; - source->regenerate(); - return 1; - } - -}; - -//1218 Psychic Venom -class APsychicVenom:public MTGAbility{ -public: - int tapped; - APsychicVenom(int _id, MTGCardInstance * _source, MTGCardInstance * _target):MTGAbility(_id, _source,_target){ - tapped = _target->tapped; - } - - void Update(float dt){ - MTGCardInstance* _target = (MTGCardInstance* )target; - int newState = _target->isTapped(); - if (newState != tapped && newState == 1){ - game->mLayers->stackLayer()->addDamage(source,_target->controller(),2); - } - tapped = newState; - } -}; - - -//1221 Serendib Efreet -class ASerendibEfreet:public MTGAbility{ -public: - ASerendibEfreet(int _id, MTGCardInstance * _source):MTGAbility(_id, _source){ - } - - void Update(float dt){ - if (newPhase == MTG_PHASE_UPKEEP && newPhase != currentPhase && game->currentPlayer == source->controller()){ - game->mLayers->stackLayer()->addDamage(source,game->currentPlayer,1); - } - } -}; - - -//1235 Aspect of Wolf -class AAspectOfWolf:public ListMaintainerAbility{ -public: - int color; - AAspectOfWolf(int _id, MTGCardInstance * _source, MTGCardInstance * _target):ListMaintainerAbility(_id, _source, _target){ - } - - int canBeInList(MTGCardInstance * card){ - - if (card->controller() == source->controller() && card->hasType("forest")) return 1; - return 0; - } - - int added(MTGCardInstance * card){ - MTGCardInstance * _target = (MTGCardInstance *) target; - int size = cards.size(); - if (size % 2 == 0){ - _target->power += 1; - }else{ - _target->addToToughness(1); - } - return 1; - } - - int removed(MTGCardInstance * card){ - MTGCardInstance * _target = (MTGCardInstance *) target; - int size = cards.size(); - if (size % 2 == 1){ - _target->power -= 1; - }else{ - _target->addToToughness(-1); - } - return 1; - } - -}; - -//1276 Wanderlust, 1148 Cursed Lands -class AWanderlust:public TriggeredAbility{ -public: - AWanderlust(int _id, MTGCardInstance * _source, MTGCardInstance * _target):TriggeredAbility(_id,_source, _target){} - - int trigger(){ - if (newPhase != currentPhase && newPhase == MTG_PHASE_UPKEEP && ((MTGCardInstance *) target)->controller()==game->currentPlayer){ - return 1; - } - return 0; - } - - int resolve(){ - game->mLayers->stackLayer()->addDamage(source,((MTGCardInstance *) target)->controller(),1); - return 1; - } -}; - -//1280 Atog -class AAtog:public TargetAbility{ -public: - Player * currentController; - int counters; - AAtog(int _id, MTGCardInstance * _source):TargetAbility(_id, _source,NULL, NULL, 0,0){ - currentController = source->controller(); - MTGGameZone * zones[] = {currentController->game->inPlay}; - tc = NEW TypeTargetChooser("artifact", zones, 1, source); - counters = 0; - } - - void Update(float dt){ - if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP){ - for (int i = 0; i < counters; i++){ - source->power-=2; - source->addToToughness(-2); - } - counters = 0; - } - TargetAbility::Update(dt); - Player * newController = source->controller(); - if (newController != currentController){ - delete tc; - MTGGameZone * zones[] = {newController->game->inPlay}; //In case Atog's controller changes - tc = NEW TypeTargetChooser("artifact", zones, 1, source); - currentController = newController; - } - } - - int resolve(){ - tc->getNextCardTarget()->controller()->game->putInGraveyard(tc->getNextCardTarget()); - source->power+=2; - source->addToToughness(2); - counters ++; - return 1; - } -}; - - - - -//1284 Dragon Whelp -class ADragonWhelp: public APowerToughnessModifierUntilEndOfTurn{ -public: - ADragonWhelp(int id, MTGCardInstance * card):APowerToughnessModifierUntilEndOfTurn(id, card, card, 1, 0, NEW ManaCost()){ - cost->add(MTG_COLOR_RED, 1); - } - - void Update(float dt){ - if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP && counters > 3){ - source->controller()->game->putInGraveyard(source); - } - APowerToughnessModifierUntilEndOfTurn::Update(dt); - } - -}; - -//1288 EarthBind -class AEarthbind:public ABasicAbilityModifier{ -public: - AEarthbind(int _id, MTGCardInstance * _source, MTGCardInstance * _target):ABasicAbilityModifier(_id,_source,_target,FLYING,0){ - if (value_before_modification) game->mLayers->stackLayer()->addDamage(source,target,2); - } -}; - -//1291 Fireball -class AFireball:public InstantAbility{ -public: - AFireball(int _id, MTGCardInstance * card, Spell * spell, int x):InstantAbility(_id, card){ - int nbtargets = spell->cursor; - int totaldamage = x+1-nbtargets; - int individualdamage = totaldamage / nbtargets; - Damageable * _target = spell->getNextDamageableTarget(); - while(_target){ - game->mLayers->stackLayer()->addDamage(source,_target,individualdamage); - _target = spell->getNextDamageableTarget(_target); - } - } -}; - -//1245 ForceOfNature -class AForceOfNature:public ActivatedAbility{ -public: - int dealDamageThisTurn; - AForceOfNature(int _id, MTGCardInstance * card):ActivatedAbility(_id,card, NEW ManaCost(),1,0){ - dealDamageThisTurn = 0; - cost->add(MTG_COLOR_GREEN,4); - } - - void Update(float dt){ - if (newPhase !=currentPhase){ - if (newPhase == MTG_PHASE_UNTAP){ - dealDamageThisTurn = 1; - }else if (newPhase == MTG_PHASE_DRAW && dealDamageThisTurn && game->currentPlayer==source->controller() ){ - game->mLayers->stackLayer()->addDamage(source,source->controller(),8); - } - } - ActivatedAbility::Update(dt); - } - - int isReactingToClick(MTGCardInstance * card){ - return (dealDamageThisTurn && currentPhase == MTG_PHASE_UPKEEP && ActivatedAbility::isReactingToClick(card)); - } - - int resolve(){ - dealDamageThisTurn = 0; - return 1; - } -}; - -//1301 KeldonWarlord -class AKeldonWarlord:public ListMaintainerAbility{ -public: - AKeldonWarlord(int _id, MTGCardInstance * _source):ListMaintainerAbility(_id, _source){ - } - - int canBeInList(MTGCardInstance * card){ - if (source->controller()->game->inPlay->hasCard(card) && card->isACreature() && !card->hasType("wall") ) return 1; - return 0; - } - - int added(MTGCardInstance * card){ - source->power += 1; - source->addToToughness(1); - return 1; - } - - int removed(MTGCardInstance * card){ - source->power -= 1; - source->addToToughness(-1); - return 1; - } - -}; - -//1302 : Kird Ape -class AKirdApe:public MTGAbility{ -public: - int init; - AKirdApe(int _id, MTGCardInstance * _source):MTGAbility(_id, _source){ - init = 0; - } - - void Update(float dt){ - if (source->controller()->game->inPlay->hasType("forest")){ - if(!init){ - init = 1; - source->power+=1; - source->addToToughness(2); - } - }else{ - if (init){ - init = 0; - source->power-=1; - source->addToToughness(-2); - } - } - } -}; - -//1309 Orcish Artilery -class AOrcishArtillery: public ADamager{ -public: - AOrcishArtillery(int _id,MTGCardInstance * card): ADamager(_id, card, NEW ManaCost(), 2){ - } - - int resolve(){ - ADamager::resolve(); - game->mLayers->stackLayer()->addDamage(source,source->controller(), 3); - return 1; - } - -}; - -//1310 Orcish Oriflame -class AOrcishOriflame:public ListMaintainerAbility{ -public: - int color; - AOrcishOriflame(int _id, MTGCardInstance * _source):ListMaintainerAbility(_id, _source){ - } - - int canBeInList(MTGCardInstance * card){ - if (source->controller() == game->currentPlayer && game->currentPlayer->game->inPlay->hasCard(card) && card->attacker) return 1; - return 0; - } - - int added(MTGCardInstance * card){ - card->power += 1; - return 1; - } - - int removed(MTGCardInstance * card){ - card->power -= 1; - return 1; - } - -}; - -//1334 Castle -class ACastle:public ListMaintainerAbility{ -public: - ACastle(int _id, MTGCardInstance * _source):ListMaintainerAbility(_id, _source){ - } - - int canBeInList(MTGCardInstance * card){ - if (source->controller()->game->inPlay->hasCard(card) && card->isACreature() && !card->isAttacker() && !card->tapped) return 1; - return 0; - } - - int added(MTGCardInstance * card){ - card->addToToughness(2); - return 1; - } - - int removed(MTGCardInstance * card){ - card->addToToughness(-2); - return 1; - } -}; - - -//1351 Island Sanctuary -class AIslandSanctuary:public MTGAbility{ -public: - int initThisTurn; - AIslandSanctuary(int _id, MTGCardInstance * _source):MTGAbility(_id, _source){ - initThisTurn = 0; - } - - void Update(float dt){ - if (currentPhase == MTG_PHASE_UNTAP && game->currentPlayer == source->controller()) initThisTurn = 0; - - if (initThisTurn && currentPhase == MTG_PHASE_COMBATATTACKERS && game->currentPlayer != source->controller()){ - MTGGameZone * zone = game->currentPlayer->game->inPlay; - for (int i = 0; i < zone->nb_cards; i++){ - MTGCardInstance * card = zone->cards[i]; - if (card->isAttacker() && !card->basicAbilities[FLYING] && !card->basicAbilities[ISLANDWALK]) card->attacker=0; - } - } - } - - int isReactingToClick(MTGCardInstance * card){ - if (card==source && game->currentPlayer == card->controller() && currentPhase == MTG_PHASE_DRAW){ - Interruptible * action = game->mLayers->stackLayer()->_(-1); - if (action->type == ACTION_DRAW) return 1; - } - return 0; - } - - - int reactToClick(MTGCardInstance * card){ - if (!isReactingToClick(card)) return 0; - game->mLayers->stackLayer()->Remove(game->mLayers->stackLayer()->_(-1)); - initThisTurn = 1; - return 1; - } -}; - -//1352 Karma -class AKarma: public TriggeredAbility{ -public: - AKarma(int _id, MTGCardInstance * _source):TriggeredAbility(_id, _source){ - } - - int trigger(){ - if (newPhase != currentPhase && newPhase == MTG_PHASE_UPKEEP) return 1; - return 0; - } - - int resolve(){ - int totaldamage = 0; - MTGGameZone * zone = game->currentPlayer->game->inPlay; - for (int i = 0; i < zone->nb_cards; i++){ - if (zone->cards[i]->hasType("swamp")) totaldamage++;; - } - if (totaldamage) game->mLayers->stackLayer()->addDamage(source,game->currentPlayer, totaldamage); - return 1; - } -}; - -//1355 Norther Paladin -class ANorthernPaladin:public TargetAbility{ -public: - ANorthernPaladin(int _id, MTGCardInstance * card):TargetAbility(_id, card){ - int _cost[] = {MTG_COLOR_WHITE, 2}; - cost = NEW ManaCost(_cost,1); - tc = NEW TargetChooser(); - } - - int resolve(){ - MTGCardInstance * card = tc->getNextCardTarget(); - if (card->hasColor(MTG_COLOR_BLACK)){ - card->controller()->game->putInGraveyard(card); - return 1; - } - return 0; - } - - -}; - -//Sedge Troll -class ASedgeTroll:public MTGAbility{ -public: - int init; - ASedgeTroll(int _id, MTGCardInstance * _source):MTGAbility(_id, _source){ - init = 0; - } - - void Update(float dt){ - if (source->controller()->game->inPlay->hasType("swamp")){ - if(!init){ - init = 1; - source->power+=1; - source->addToToughness(1); - } - }else{ - if (init){ - init = 0; - source->power-=1; - source->addToToughness(-1); - } - } - } -}; - -//Soul Net -class ASoulNet:public ActivatedAbility{ -public: - PutInGraveyard * latest; - PutInGraveyard * newDead; - ASoulNet(int _id, MTGCardInstance * card):ActivatedAbility(_id, card,0,0,0){ - int _cost[] = {MTG_COLOR_ARTIFACT, 1}; - cost = NEW ManaCost(_cost,1); - latest = ((PutInGraveyard *) GameObserver::GetInstance()->mLayers->stackLayer()->getPrevious(NULL,ACTION_PUTINGRAVEYARD,RESOLVED_OK)); - newDead = latest; - } - - int isReactingToClick(MTGCardInstance * card){ - newDead = ((PutInGraveyard *) GameObserver::GetInstance()->mLayers->stackLayer()->getPrevious(NULL,ACTION_PUTINGRAVEYARD,RESOLVED_OK)); - if (newDead && newDead != latest && newDead->card->isACreature()) - return ActivatedAbility::isReactingToClick(card); - return 0; - } - int resolve(){ - latest = newDead; - source->controller()->life++; - return 1; - } -}; - - -//Stasis -class AStasis:public ActivatedAbility{ -public: - int paidThisTurn; - AStasis(int _id, MTGCardInstance * card):ActivatedAbility(_id,card, NEW ManaCost(),1,0){ - paidThisTurn = 1; - cost->add(MTG_COLOR_BLUE,1); - } - - void Update(float dt){ - //Upkeep Cost - if (newPhase !=currentPhase){ - if (newPhase == MTG_PHASE_UPKEEP){ - paidThisTurn = 0; - }else if (!paidThisTurn && newPhase > MTG_PHASE_UPKEEP && game->currentPlayer==source->controller() ){ - game->currentPlayer->game->putInGraveyard(source); - paidThisTurn = 1; - } - } - //Stasis Effect - for (int i = 0; i < 2; i++){ - game->phaseRing->removePhase(MTG_PHASE_UNTAP,game->players[i]); - } - - //Parent Class Method Call - ActivatedAbility::Update(dt); - } - - int isReactingToClick(MTGCardInstance * card){ - return (!paidThisTurn && currentPhase == MTG_PHASE_UPKEEP && ActivatedAbility::isReactingToClick(card)); - } - - int resolve(){ - paidThisTurn = 1; - return 1; - } - - int destroy(){ - for (int i = 0; i < 2; i++){ - game->phaseRing->addPhaseBefore(MTG_PHASE_UNTAP,game->players[i],MTG_PHASE_UPKEEP,game->players[i]); - } - return 1; - } -}; - - - -//--------------Addon Abra------------------ -//ShieldOfTheAge -class AShieldOfTheAge: public TargetAbility{ -public: - AShieldOfTheAge(int _id, MTGCardInstance * card):TargetAbility(_id,card,NEW DamageTargetChooser(card,_id),NEW ManaCost(),0,0){ - cost->add(MTG_COLOR_ARTIFACT,2); - } - - int resolve(){ - Damage * damage = tc->getNextDamageTarget(); - if (!damage) return 0; - game->mLayers->stackLayer()->Fizzle(damage); - return 1; - } -}; - -// GiveLifeForTappedType -class AGiveLifeForTappedType:public MTGAbility{ -public: - char type[20]; - int nbtypestapped; - - int counttypesTapped(){ - int result = 0; - MTGInPlay * inplay = source->controller()->opponent()->game->inPlay; - for (int i = 0; i < inplay->nb_cards; i++){ - MTGCardInstance * card = inplay->cards[i]; - if (card->tapped && card->hasType(type)) result++; - } - return result; - } - - AGiveLifeForTappedType(int _id, MTGCardInstance * source, const char * _type):MTGAbility(_id, source){ - sprintf(type,"%s",_type);{ - nbtypestapped = counttypesTapped(); - } - } - - void Update(float dt){ - int newcount = counttypesTapped(); - for (int i=0; i < newcount - nbtypestapped; i++){ - source->controller()->life++; - } - nbtypestapped = newcount; - } -}; - -// People of the Woods -class APeopleOfTheWoods:public ListMaintainerAbility{ -public: - APeopleOfTheWoods(int _id, MTGCardInstance * _source):ListMaintainerAbility(_id, _source){ - } - - int canBeInList(MTGCardInstance * card){ - if (source->controller()->game->inPlay->hasCard(card) && card->hasType("forest") ) return 1; - return 0; - } - - int added(MTGCardInstance * card){ - source->addToToughness(1); - return 1; - } - - int removed(MTGCardInstance * card){ - source->addToToughness(-1); - return 1; - } - -}; - -//Abomination Kill blocking creature if white or green -class AAbomination :public MTGAbility{ -public: - MTGCardInstance * opponents[20]; - int nbOpponents; - AAbomination (int _id, MTGCardInstance * _source):MTGAbility(_id, _source){ - nbOpponents = 0; - } - - void Update(float dt){ - if (newPhase != currentPhase){ - if( newPhase == MTG_PHASE_COMBATDAMAGE){ - nbOpponents = 0; - MTGCardInstance * opponent = source->getNextOpponent(); - while (opponent && opponent->hasColor(MTG_COLOR_GREEN) || opponent->hasColor(MTG_COLOR_WHITE)){ - opponents[nbOpponents] = opponent; - nbOpponents ++; - opponent = source->getNextOpponent(opponent); - } - }else if (newPhase == MTG_PHASE_COMBATEND){ - for (int i = 0; i < nbOpponents ; i++){ - game->mLayers->stackLayer()->addPutInGraveyard(opponents[i]); - } - } - } - } - - int testDestroy(){ - if(!game->isInPlay(source) && currentPhase != MTG_PHASE_UNTAP){ - return 0; - }else{ - return MTGAbility::testDestroy(); - } - } -}; - - - -//Minion of Leshrac -class AMinionofLeshrac: public TargetAbility{ -public: - int paidThisTurn; - AMinionofLeshrac(int _id, MTGCardInstance * source):TargetAbility(_id, source, NEW CreatureTargetChooser(),0,1,0){ - paidThisTurn = 1; - } - - void Update(float dt){ - if (newPhase != currentPhase && source->controller() == game->currentPlayer){ - if (newPhase == MTG_PHASE_UNTAP){ - paidThisTurn = 0; - }else if( newPhase == MTG_PHASE_UPKEEP + 1 && !paidThisTurn){ - game->mLayers->stackLayer()->addDamage(source,source->controller(), 5); - source->tapped = 1; - } - } - TargetAbility::Update(dt); - } - - int isReactingToClick(MTGCardInstance * card){ - if (currentPhase != MTG_PHASE_UPKEEP || paidThisTurn) return 0; - return TargetAbility::isReactingToClick(card); - } - - int resolve(){ - MTGCardInstance * card = tc->getNextCardTarget(); - if (card && card != source && card->controller() == source->controller()){ - card->controller()->game->putInGraveyard(card); - paidThisTurn = 1; - return 1; - } - return 0; - } - -}; - -//2703 Lost Order of Jarkeld -class ALostOrderofJarkeld:public ListMaintainerAbility{ -public: - ALostOrderofJarkeld(int _id, MTGCardInstance * _source):ListMaintainerAbility(_id, _source){ - } - - int canBeInList(MTGCardInstance * card){ - if (card==source || (game->currentPlayer->game->inPlay->hasCard(card) && card->isACreature()) ) return 1; - return 0; - } - - int added(MTGCardInstance * card){ - source->power += 1; - source->addToToughness(1); - return 1; - } - - int removed(MTGCardInstance * card){ - source->power -= 1; - source->addToToughness(-1); - return 1; - } - -}; - -//CreaturePowerToughnessModifierForAllTypeControlled -class ACreaturePowerToughnessModifierForAllTypeControlled:public ListMaintainerAbility{ -public: - char type[20]; - ACreaturePowerToughnessModifierForAllTypeControlled(int _id, MTGCardInstance * _source, const char * _type):ListMaintainerAbility(_id, _source){ - } - - int canBeInList(MTGCardInstance * card){ - if (source->controller()->game->inPlay->hasCard(card) && card->hasType(type) ) return 1; - return 0; - } - - int added(MTGCardInstance * card){ - source->power += 1; - source->addToToughness(1); - return 1; - } - - int removed(MTGCardInstance * card){ - source->power -= 1; - source->addToToughness(-1); - return 1; - } - -}; - -//GenericKirdApe -class AGenericKirdApe:public MTGAbility{ -public: - int init; - char type [20]; - int power; - int toughness; - AGenericKirdApe(int _id, MTGCardInstance * _source, const char * _type, int _power, int _toughness):MTGAbility(_id, _source){ - init = 0; - } - - void Update(float dt){ - if (source->controller()->game->inPlay->hasType(type)){ - if(!init){ - init = 1; - source->power+=power; - source->addToToughness(toughness); - } - }else{ - if (init){ - init = 0; - source->power-=power; - source->addToToughness(-toughness); - } - } - } -}; - - -//Rampage ability Tentative 2 -class ARampageAbility:public MTGAbility{ -public: - int nbOpponents; - int PowerModifier; - int ToughnessModifier; - int modifier; - ARampageAbility(int _id, MTGCardInstance * _source,int _PowerModifier, int _ToughnessModifier):MTGAbility(_id, _source){ - modifier=0; - } - void Update(float dt){ - if (source->isAttacker()){ - MTGInPlay * inPlay = game->opponent()->game->inPlay; - for (int i = 0; i < inPlay->nb_cards; i ++){ - MTGCardInstance * current = inPlay->cards[i]; - if (current->isDefenser()){ - modifier++; - } - } - source->power+= (PowerModifier * modifier); - source->addToToughness(ToughnessModifier * modifier); - } - } -}; - - -//Rampage ability Tentative 1 - Did not work as expected -class A1RampageAbility:public MTGAbility{ -public: - MTGCardInstance * opponents[20]; - int nbOpponents; - int PowerModifier; - int ToughnessModifier; - A1RampageAbility(int _id, MTGCardInstance * _source,int _PowerModifier, int _ToughnessModifier):MTGAbility(_id, _source){ - nbOpponents = 0; - } - - void Update(float dt){ - if (source->isAttacker()){ - if (newPhase != currentPhase){ - if( newPhase == MTG_PHASE_COMBATDAMAGE){ - nbOpponents = 0; - MTGCardInstance * opponent = source->getNextOpponent(); - while (opponent){ - opponents[nbOpponents] = opponent; - nbOpponents ++; - source->power+= PowerModifier; - source->addToToughness(ToughnessModifier); - opponent = source->getNextOpponent(opponent); - } - } - } - } - } -}; -#endif +#ifndef _CARDS_H_ +#define _CARDS_H_ + +#include "MTGAbility.h" +#include "GroupOfCards.h" +#include "ManaCost.h" +#include "CardDescriptor.h" +#include "AIPlayer.h" +#include "CardDisplay.h" +#include "Subtypes.h" +#include "CardGui.h" + +#include +#include + + +#include +using std::map; + +/* + Generic classes +*/ + + +//Drawer, allows to draw a card for a cost: + +class ADrawer:public ActivatedAbility{ + public: + int nbcards; + ADrawer(int _id, MTGCardInstance * card,ManaCost * _cost, int _nbcards = 1, int _tap = 1):ActivatedAbility(_id, card,_cost,0,_tap),nbcards(_nbcards){ + } + + int resolve(){ + game->mLayers->stackLayer()->addDraw(source->controller(),nbcards); + return 1; + } +}; + + +//Destroyer. TargetAbility +class ADestroyer:public TargetAbility{ + public: + int bury; + ADestroyer(int _id, MTGCardInstance * _source, TargetChooser * _tc = NULL, int _bury = 0):TargetAbility(_id,_source, tc),bury(_bury){ + if (!tc) tc = NEW CreatureTargetChooser(); + } + + int resolve(){ + MTGCardInstance * _target = tc->getNextCardTarget(); + if(_target){ + if (bury){ + _target->controller()->game->putInGraveyard(_target); + }else{ + game->mLayers->stackLayer()->addPutInGraveyard(_target); + } + return 1; + } + return 0; + } + +}; + +//Destroyer. TargetAbility +class ABurier:public ADestroyer{ + public: + ABurier(int _id, MTGCardInstance * _source, TargetChooser * _tc = NULL):ADestroyer(_id,_source, tc,1){ + } +}; + + +/*Changes one of the basic abilities of target + source : spell + target : spell target (creature) + modifier : 1 to add the ability, 0 to remove it + _ability : Id of the ability, as described in mtgdefinitions +*/ +class ABasicAbilityModifier:public MTGAbility{ + public: + int modifier; + int ability; + int value_before_modification; + ABasicAbilityModifier(int _id, MTGCardInstance * _source, MTGCardInstance * _target, int _ability, int _modifier = 1): MTGAbility(_id,_source,_target),modifier(_modifier),ability(_ability){ + value_before_modification = ((MTGCardInstance * )target)->basicAbilities[ability]; + ((MTGCardInstance * )target)->basicAbilities[ability]=modifier; + } + + int destroy(){ + if (((MTGCardInstance * )target)->basicAbilities[ability] == modifier){ + ((MTGCardInstance * )target)->basicAbilities[ability] = value_before_modification; + return 1; + }else{ + //BUG !!! + return 0; + } + } +}; + +//Modifies an ability until end of turn. Needs a target +class ABasicAbilityModifierUntilEOT:public TargetAbility{ + public: + MTGCardInstance * mTargets[50]; + int nbTargets; + int modifier; + int stateBeforeActivation[50]; + int ability; + ABasicAbilityModifierUntilEOT(int _id, MTGCardInstance * _source, int _ability, ManaCost * _cost, TargetChooser * _tc = NULL, int _modifier = 1): TargetAbility(_id,_source,_cost),modifier(_modifier), ability(_ability){ + nbTargets = 0; + tc = _tc; + if (!tc) tc = NEW CreatureTargetChooser(_source); + } + + void Update(float dt){ + if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP){ + for (int i = 0; i < nbTargets; i++){ + MTGCardInstance * mTarget = mTargets[i]; + if(mTarget && mTarget->basicAbilities[ability]){ + mTarget->basicAbilities[ability] = stateBeforeActivation[i]; + } + } + nbTargets = 0; + } + TargetAbility::Update(dt); + } + + + int resolve(){ + MTGCardInstance * mTarget = tc->getNextCardTarget(); + if (mTarget){ + mTargets[nbTargets] = mTarget; + stateBeforeActivation[nbTargets] = mTarget->basicAbilities[ability]; + mTarget->basicAbilities[ability] = modifier; + nbTargets++; + } + return 1; + } + + +}; + +/*Instants that modifies a basic ability until end of turn */ +class AInstantBasicAbilityModifierUntilEOT: public InstantAbility{ + public: + int stateBeforeActivation; + int ability; + AInstantBasicAbilityModifierUntilEOT(int _id, MTGCardInstance * _source, MTGCardInstance * _target, int _ability, int value):InstantAbility(_id, _source, _target),ability(_ability){ + stateBeforeActivation = _target->basicAbilities[ability]; + _target->basicAbilities[ability] = value; + } + + int destroy(){ + ((MTGCardInstance *)target)->basicAbilities[ability] = stateBeforeActivation; + return 1; + } + +}; + +//Alteration of Ability until of turn (Aura) +class ABasicAbilityAuraModifierUntilEOT: public ActivatedAbility{ + public: + int stateBeforeActivation; + int ability; + int value; + ABasicAbilityAuraModifierUntilEOT(int _id, MTGCardInstance * _source, MTGCardInstance * _target, ManaCost * _cost, int _ability, int _value = 1):ActivatedAbility(_id,_source, _cost, 0,0), ability(_ability), value(_value){ + target = _target; + stateBeforeActivation = _target->basicAbilities[ability]; + } + + void Update(float dt){ + if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP){ + MTGCardInstance * _target = (MTGCardInstance *) target; + _target->basicAbilities[ability] = stateBeforeActivation; + } + ActivatedAbility::Update(dt); + } + + int resolve(){ + MTGCardInstance * _target = (MTGCardInstance *) target; + stateBeforeActivation = _target->basicAbilities[ability]; + _target->basicAbilities[ability] = value; + return 1; + } + +}; + + + +/*Gives life each time a spell matching CardDescriptor's criteria are match . Optionnal manacost*/ +class ASpellCastLife:public MTGAbility{ + public: + CardDescriptor trigger; + ManaCost * cost; + int life; + MTGCardInstance * lastUsedOn; + MTGCardInstance * lastChecked; + ASpellCastLife(int id, MTGCardInstance * _source, CardDescriptor _trigger, ManaCost * _cost, int _life): MTGAbility(id, _source), trigger(_trigger), cost(_cost), life(_life){ + } + ASpellCastLife(int id, MTGCardInstance * _source, int color, ManaCost * _cost, int _life): MTGAbility(id, _source), cost(_cost), life(_life){ + trigger.setColor(color); + } + + int isReactingToClick(MTGCardInstance * _card){ + if (_card == source && game->currentlyActing()->game->inPlay->hasCard(source)){ + if (game->currentlyActing()->getManaPool()->canAfford(cost)){ + Interruptible * laststackitem = game->mLayers->stackLayer()->_(-1); + if (laststackitem && laststackitem->type == ACTION_SPELL){ + Spell * spell = (Spell*)laststackitem; + if (spell->source != lastUsedOn && trigger.match(spell->source)){ + lastChecked = spell->source; + return 1; + } + } + } + } + return 0; + } + + int reactToClick(MTGCardInstance * _card){ + if (!isReactingToClick( _card)) return 0; + game->currentlyActing()->getManaPool()->pay(cost); + game->currentlyActing()->life+=life; + lastUsedOn = lastChecked; + return 1; + } + +}; + +//Allows to untap at any moment for an amount of mana +class AUnBlocker:public MTGAbility{ + public: + ManaCost * cost; + AUnBlocker(int id, MTGCardInstance * _source, MTGCardInstance * _target, ManaCost * _cost):MTGAbility(id, _source, _target), cost(_cost){ + } + + + int isReactingToClick(MTGCardInstance * _card){ + if (_card == target && game->currentlyActing()->game->inPlay->hasCard(source) && (MTGCardInstance *) _card->isTapped()){ + if (game->currentlyActing()->getManaPool()->canAfford(cost)){ + return 1; + } + } + return 0; + } + + int reactToClick(MTGCardInstance * _card){ + if (!isReactingToClick( _card)) return 0; + game->currentlyActing()->getManaPool()->pay(cost); + _card->untap(); + return 1; + } +}; + +//Allows to untap target card once per turn for a manaCost +class AUntaperOnceDuringTurn:public AUnBlocker{ + public: + int untappedThisTurn; + int onlyPlayerTurn; + AUntaperOnceDuringTurn(int id, MTGCardInstance * _source, MTGCardInstance * _target, ManaCost * _cost, int _onlyPlayerTurn = 1):AUnBlocker(id, _source, _target, _cost){ + onlyPlayerTurn = _onlyPlayerTurn; + untappedThisTurn = 0; + } + + void Update(float dt){ + if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP) untappedThisTurn = 0; + AUnBlocker::Update(dt); + } + + int isReactingToClick(MTGCardInstance * card){ + if (onlyPlayerTurn && game->currentPlayer!=source->controller()) return 0; + if (untappedThisTurn) return 0; + return AUnBlocker::isReactingToClick(card); + } + + int reactToClick(MTGCardInstance * card){ + untappedThisTurn = 1; + return AUnBlocker::reactToClick(card); + } +}; + +//Alteration of Power and Toughness (enchantments) +class APowerToughnessModifier: public MTGAbility{ + public: + int power, toughness; + APowerToughnessModifier(int id, MTGCardInstance * _source, MTGCardInstance * _target, int _power, int _toughness):MTGAbility(id,_source,_target),power(_power),toughness(_toughness){ + _target->power += power; + _target->addToToughness(toughness); + } + + int destroy(){ + ((MTGCardInstance *)target)->power -= power; + ((MTGCardInstance *)target)->addToToughness(-toughness); + return 1; + } +}; + +// Permanent life alteration evry turn of the target's controller. Useful only for unstable mutation currently +class APowerToughnessModifierRegularCounter:public MTGAbility{ + public: + int power, toughness; + int phase; + APowerToughnessModifierRegularCounter(int id, MTGCardInstance * _source, MTGCardInstance * _target, int _phase, int _power, int _toughness):MTGAbility(id,_source,_target),power(_power),toughness(_toughness), phase(_phase){ + } + + void Update(float dt){ + if (newPhase !=currentPhase && newPhase==phase && game->currentPlayer==((MTGCardInstance *)target)->controller()){ + ((MTGCardInstance *)target)->power += power; + ((MTGCardInstance *)target)->addToToughness(toughness); + } + } + +}; + + +//Alteration of Power and Toughness until end of turn (TargetAbility) +// Gives +n/+m until end of turn to any card that's a target +class ATargetterPowerToughnessModifierUntilEOT: public TargetAbility{ + public: + MTGCardInstance * mTargets[50]; + int nbTargets; + int power, toughness; + + ATargetterPowerToughnessModifierUntilEOT(int _id, MTGCardInstance * _source, int _power, int _toughness, ManaCost * _cost, TargetChooser * _tc = NULL):TargetAbility(_id,_source,_tc,_cost,0),power(_power),toughness(_toughness){ + if (!tc) tc = NEW CreatureTargetChooser(_source); + nbTargets = 0; + } + + + void Update(float dt){ + if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP){ + for (int i = 0; i < nbTargets; i++){ + MTGCardInstance * mTarget = mTargets[i]; + if(mTarget){ + mTarget->power-=power; + mTarget->addToToughness(-toughness); + } + } + nbTargets = 0; + } + TargetAbility::Update(dt); + } + + + int resolve(){ + MTGCardInstance * mTarget = tc->getNextCardTarget(); + if (mTarget){ + mTargets[nbTargets] = mTarget; + mTarget->power+= power; + mTarget->addToToughness(toughness); + nbTargets++; + } + return 1; + } + +}; + + + +//Alteration of Power and Toughness until end of turn (Aura) +class APowerToughnessModifierUntilEndOfTurn: public MTGAbility{ + public: + int power, toughness; + int counters; + int maxcounters; + ManaCost * cost; + APowerToughnessModifierUntilEndOfTurn(int id, MTGCardInstance * _source, MTGCardInstance * _target, int _power, int _toughness, ManaCost * _cost, int _maxcounters = 0):MTGAbility(id,_source,_target),power(_power),toughness(_toughness),maxcounters(_maxcounters), cost(_cost){ + counters = 0; + } + + void Update(float dt){ + if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP){ + while(counters){ + ((MTGCardInstance *)target)->power -= power; + ((MTGCardInstance *)target)->addToToughness(-toughness); + counters--; + } + } + } + + int isReactingToClick(MTGCardInstance * _card){ + if (_card == source && (!maxcounters || counters < maxcounters) && game->currentlyActing()->game->inPlay->hasCard(source)){ + if (game->currentlyActing()->getManaPool()->canAfford(cost)){ + return 1; + } + } + return 0; + } + + int reactToClick(MTGCardInstance * _card){ + if (!isReactingToClick( _card)) return 0; + game->currentlyActing()->getManaPool()->pay(cost); + ((MTGCardInstance *)target)->power += power; + ((MTGCardInstance *)target)->addToToughness(toughness); + counters++; + return 1; + } +}; + + +//Alteration of Power and toughness until end of turn (instant) +class AInstantPowerToughnessModifierUntilEOT: public InstantAbility{ + public: + int power, toughness; + AInstantPowerToughnessModifierUntilEOT(int _id, MTGCardInstance * _source, MTGCardInstance * _target, int _power, int _toughness): InstantAbility(_id, _source, _target), power(_power), toughness(_toughness){ + } + + int resolve(){ + ((MTGCardInstance *)target)->power +=power; + ((MTGCardInstance *)target)->addToToughness(toughness); + return 1; + } + + int destroy(){ + ((MTGCardInstance *)target)->power -=power; + ((MTGCardInstance *)target)->addToToughness(-toughness); + return 1; + } + +}; +//Untap Blockers with simple Mana Mechanism +class AUntapManaBlocker: public Blocker{ + public: + AUntapManaBlocker(int id, MTGCardInstance * card, ManaCost * _cost):Blocker(id, card, _cost){ + } + + AUntapManaBlocker(int id, MTGCardInstance * card, MTGCardInstance * _target, ManaCost * _cost):Blocker(id, card,_target, _cost){ + } +}; + +/* Spell Counters (Enchantment) for a mana cost */ +//LifeForce +class ASpellCounterEnchantment:public TargetAbility{ + public: + + ASpellCounterEnchantment(int _id, MTGCardInstance * _source, ManaCost * _cost,int color = -1, int _tap = 0):TargetAbility(_id,_source,NEW SpellTargetChooser(_source,color),_cost,0,_tap){ + } + + int resolve(){ + Spell * _target = tc->getNextSpellTarget(); + if(_target){ + game->mLayers->stackLayer()->Fizzle(_target); + return 1; + } + return 0; + } + +}; + +/*Mana Producers (lands) +//These have a reactToClick function, and therefore two manaProducers on the same card conflict with each other +//That means the player has to choose one. although that is perfect for cards such as birds of paradise or badlands, +other solutions need to be provided for abilities that add mana (ex: mana flare) +*/ +/* + Currently the mana is added to the pool AFTER the animation + This is VERY BAD, since we don't have any control on the duration of the animation. This can lead to bugs with + the AI, who is expecting to have the mana in its manapool right after clicking the land card !!! + The sum of "dt" has to be 0.25 for the mana to be in the manapool currently +*/ + +class AManaProducer: public MTGAbility{ + protected: + ManaCost * cost; + ManaCost * output; + string menutext; + float x0,y0,x1,y1,x,y; + float animation; + Player * controller; + + hgeParticleSystem * mParticleSys; + public: + AManaProducer(int id, MTGCardInstance * card, ManaCost * _output, ManaCost * _cost = NULL ):MTGAbility(id, card){ + LOG("==Creating ManaProducer Object"); + cost = _cost; + output=_output; + x1 = 10; + y1 = 220; + Player * player = card->controller(); + if (player == game->players[1]) y1 = 100; + x = x1; + y = y1; + animation = 0.f; + mParticleSys = NULL; + menutext = ""; + + int landColor = output->getMainColor(); + + if (landColor == MTG_COLOR_RED){ + mParticleSys = NEW hgeParticleSystem("graphics/manared.psi",GameApp::CommonRes->GetQuad("particles")); + }else if (landColor == MTG_COLOR_BLUE){ + mParticleSys = NEW hgeParticleSystem("graphics/manablue.psi", GameApp::CommonRes->GetQuad("particles")); + }else if (landColor == MTG_COLOR_GREEN){ + mParticleSys = NEW hgeParticleSystem("graphics/managreen.psi", GameApp::CommonRes->GetQuad("particles")); + }else if (landColor == MTG_COLOR_BLACK){ + mParticleSys = NEW hgeParticleSystem("graphics/manablack.psi", GameApp::CommonRes->GetQuad("particles")); + }else if (landColor == MTG_COLOR_WHITE){ + mParticleSys = NEW hgeParticleSystem("graphics/manawhite.psi", GameApp::CommonRes->GetQuad("particles")); + }else{ + mParticleSys = NEW hgeParticleSystem("graphics/mana.psi", GameApp::CommonRes->GetQuad("particles")); + } + + + + LOG("==ManaProducer Object Creation successful !"); + } + + void Update(float dt){ + if (mParticleSys) mParticleSys->Update(dt); + if (animation){ + x = (1.f - animation)*x1 + animation * x0; + y = (1.f - animation)*y1 + animation * y0; + if (mParticleSys) mParticleSys->MoveTo(x, y); + if (mParticleSys && animation == 1.f) mParticleSys->Fire(); + animation -= 4 *dt; + if (animation < 0){ + animation = 0; + controller->getManaPool()->add(output); + if (mParticleSys) mParticleSys->Stop(); + } + } + + } + + void Render(){ + JRenderer * renderer = JRenderer::GetInstance(); + if (animation){ + renderer->SetTexBlend(BLEND_SRC_ALPHA, BLEND_ONE); + if (mParticleSys) mParticleSys->Render(); + // set normal blending + renderer->SetTexBlend(BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA); + } + + } + + int isReactingToClick(MTGCardInstance * _card){ + int result = 0; + if (_card == source && !source->isTapped() && game->currentlyActing()->game->inPlay->hasCard(source) && (source->hasType("land") || !source->hasSummoningSickness()) ){ + if (!cost || game->currentlyActing()->getManaPool()->canAfford(cost)) result = 1; + } + return result; + } + + int reactToClick(MTGCardInstance * _card){ + if (!isReactingToClick( _card)) return 0; + source->tapped = 1; + if (cost) GameObserver::GetInstance()->currentlyActing()->getManaPool()->pay(cost); + animation = 1.f; + CardGui * cardg = game->mLayers->playLayer()->getByCard(source); + if (cardg){ + x0 = cardg->x + 15; + y0 = cardg->y + 20; + } + controller = source->controller(); + return 1; + } + + const char * getMenuText(){ + if (menutext.size())return menutext.c_str(); + menutext = "Add "; + char buffer[128]; + int alreadyHasOne = 0; + for (int i= 0; i < 6; i++){ + int value = output->getCost(i); + if (value){ + if (alreadyHasOne) menutext.append(","); + sprintf(buffer, "%i ", value); + menutext.append(buffer); + switch (i){ + case MTG_COLOR_RED: + menutext.append("red"); + break; + case MTG_COLOR_BLUE: + menutext.append("blue"); + break; + case MTG_COLOR_GREEN: + menutext.append("green"); + break; + case MTG_COLOR_WHITE: + menutext.append("white"); + break; + case MTG_COLOR_BLACK: + menutext.append("black"); + break; + default: + break; + } + alreadyHasOne = 1; + } + } + menutext.append(" mana"); + return menutext.c_str(); + } + + int testDestroy(){ + if (animation >0) return 0; + return MTGAbility::testDestroy(); + } + + ~AManaProducer(){ + LOG("==Destroying ManaProducer Object"); + if (cost) delete cost; + SAFE_DELETE(output); + if (mParticleSys) delete mParticleSys; + LOG("==Destroying ManaProducer Object Successful!"); + } + +}; + + +/* Lifelink Ability */ +class ALifeLink:public MTGAbility{ + public: + int nbdamagesthisturn; + Damage * lastDamage; + ALifeLink(int _id, MTGCardInstance * _source):MTGAbility(_id, _source){ + nbdamagesthisturn = 0; + lastDamage = NULL; + } + + void Update(float dt){ + ActionStack * as = game->mLayers->stackLayer(); + int totaldamages = as->count(ACTION_DAMAGE,RESOLVED_OK); + if ( totaldamages > nbdamagesthisturn){ + Damage * damage = ((Damage * )as->getNext(lastDamage,ACTION_DAMAGE, RESOLVED_OK)); + while(damage){ + lastDamage = damage; + if (damage->source == source){ + source->controller()->life+= damage->damage; + } + damage = ((Damage * )as->getNext(lastDamage,ACTION_DAMAGE, RESOLVED_OK)); + } + }else if (totaldamages ==0){ + lastDamage = NULL; + } + nbdamagesthisturn = totaldamages; + } + +}; + + +//Circle of Protections +class ACircleOfProtection: public TargetAbility{ + public: + ACircleOfProtection(int _id, MTGCardInstance * source, int _color):TargetAbility(_id,source,NEW DamageTargetChooser(source,_color),NEW ManaCost(),0,0){ + cost->add(MTG_COLOR_ARTIFACT,1); + } + + int resolve(){ + Damage * damage = tc->getNextDamageTarget(); + if (!damage) return 0; + game->mLayers->stackLayer()->Fizzle(damage); + return 1; + } +}; + +//Basic regeneration mechanism for a Mana cost +class AStandardRegenerate:public ActivatedAbility{ + public: + AStandardRegenerate(int _id, MTGCardInstance * _source, MTGCardInstance * _target, ManaCost * _cost):ActivatedAbility(_id,_source,_cost,0,0){ + target = _target; + } + + int resolve(){ + MTGCardInstance * _target = (MTGCardInstance *)target; + _target->regenerate(); + PutInGraveyard * action = ((PutInGraveyard *) game->mLayers->stackLayer()->getNext(NULL,ACTION_PUTINGRAVEYARD,NOT_RESOLVED)); + while(action){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("Fizzling due to regenerate! \n"); +#endif + if (action->card == _target){ + game->mLayers->stackLayer()->Fizzle(action); + } + action = ((PutInGraveyard *) game->mLayers->stackLayer()->getNext(action,ACTION_PUTINGRAVEYARD,NOT_RESOLVED)); + } + return 1; + } + +}; + +/*Gives protection to a target */ +class AProtectionFrom:public MTGAbility{ + public: + CardDescriptor * cd; + void initProtection(){ + ((MTGCardInstance *)target)->addProtection(cd); + } + + AProtectionFrom(int _id, MTGCardInstance * _source, MTGCardInstance * _target, CardDescriptor * _cd):MTGAbility(_id, _source, _target),cd(_cd){ + initProtection(); + } + AProtectionFrom(int _id, MTGCardInstance * _source, MTGCardInstance * _target, int color):MTGAbility(_id, _source, _target){ + cd = NEW CardDescriptor(); + cd->colors[color] = 1; + initProtection(); + } + + int destroy(){ + ((MTGCardInstance *)target)->removeProtection(cd); + return 1; + } + +}; + +//Aura Enchantments that provide controller of target life or damages at a given phase of their turn +class ARegularLifeModifierAura:public MTGAbility{ + public: + int life; + int phase; + int onlyIfTargetTapped; + ARegularLifeModifierAura(int id, MTGCardInstance * _source, MTGCardInstance * _target, int _phase, int _life, int _onlyIfTargetTapped=0):MTGAbility(id,_source,_target),life(_life), phase(_phase),onlyIfTargetTapped(_onlyIfTargetTapped){ + } + + void Update(float dt){ + if (newPhase !=currentPhase && newPhase==phase && game->currentPlayer==((MTGCardInstance *)target)->controller()){ + if (!onlyIfTargetTapped || ((MTGCardInstance *)target)->tapped){ + if (life > 0){ + game->currentPlayer->life+=life; + }else{ + game->mLayers->stackLayer()->addDamage(source, game->currentPlayer, -life); + } + } + } + } +}; + + +//ExaltedAbility (Shards of Alara) +class AExalted:public ListMaintainerAbility{ + public: + int power, toughness; + MTGCardInstance * luckyWinner; + AExalted(int _id, MTGCardInstance * _source, int _power = 1, int _toughness = 1):ListMaintainerAbility(_id, _source),power(_power),toughness(_toughness){ + luckyWinner = NULL; + } + + + int canBeInList(MTGCardInstance * card){ + if (card->isAttacker() && game->currentPlayer == source->controller()) return 1; + return 0; + } + + int added(MTGCardInstance * card){ + if(cards.size() == 1){ + luckyWinner = cards.begin()->first; + luckyWinner->addToToughness(toughness); + luckyWinner->power+=power; + }else if (cards.size() == 2){ + luckyWinner->addToToughness(-toughness); + luckyWinner->power-=power; + } + return 1; + } + + int removed(MTGCardInstance * card){ + if(cards.size() == 1){ + luckyWinner = cards.begin()->first; + luckyWinner->addToToughness(toughness); + luckyWinner->power+=power; + }else if (cards.size() == 0){ + luckyWinner->addToToughness(-toughness); + luckyWinner->power-=power; + } + return 1; + } + +}; + + +//ExaltedAbility for basic abilities (Shards of Alara) +class AExaltedAbility:public ListMaintainerAbility{ + public: + int ability; + MTGCardInstance * luckyWinner; + AExaltedAbility(int _id, MTGCardInstance * _source, int _ability):ListMaintainerAbility(_id, _source),ability(_ability){ + luckyWinner = NULL; + } + + + int canBeInList(MTGCardInstance * card){ + if (card->isAttacker() && game->currentPlayer == source->controller()) return 1; + return 0; + } + + int added(MTGCardInstance * card){ + luckyWinner = cards.begin()->first; + if(cards.size() == 1){ + luckyWinner->basicAbilities[ability]+=1; + }else if (cards.size() == 2){ + luckyWinner->basicAbilities[ability]-=1; + } + return 1; + } + + int removed(MTGCardInstance * card){ + if(cards.size() == 1){ + luckyWinner->basicAbilities[ability]+=1; + }else if (cards.size() == 0){ + luckyWinner->basicAbilities[ability]-=1; + } + return 1; + } + +}; + + +//Converts lands to creatures (Kormus bell, Living lands) +class AConvertLandToCreatures:public ListMaintainerAbility{ + public: + int type; + int power, toughness; + AConvertLandToCreatures(int _id, MTGCardInstance * _source, const char * _type, int _power = 1, int _toughness = 1):ListMaintainerAbility(_id, _source),power(_power),toughness(_toughness){ + type = Subtypes::subtypesList->Add(_type); + } + + + int canBeInList(MTGCardInstance * card){ + if (card->hasType(type)) return 1; + return 0; + } + + int added(MTGCardInstance * card){ + card->power = 1; + card->setToughness(1); + card->setSubtype("creature"); + return 1; + } + + int removed(MTGCardInstance * card){ + card->removeType("creature"); + return 1; + } + +}; + +//Lords (Merfolk lord...) give power and toughness to OTHER creatures of their type, they can give them special abilities, regeneration +class ALord:public ListMaintainerAbility{ + public: + string type; + int power, toughness; + int ability; + ManaCost * regenCost; + map regenerations; + ALord(int _id, MTGCardInstance * card, const char * _type, int _power = 0 , int _toughness = 0, int _ability = -1, ManaCost * _regenCost = NULL):ListMaintainerAbility(_id,card){ + type = _type; + power = _power; + toughness = _toughness; + ability = _ability; + regenCost = _regenCost; + } + + int canBeInList(MTGCardInstance * card){ + if (card!=source && card->isACreature() && card->hasSubtype(type)) return 1; + return 0; + } + + int added(MTGCardInstance * card){ + card->power += power; + card->addToToughness(toughness); + if (ability != -1) card->basicAbilities[ability] +=1; + if (regenCost){ + AStandardRegenerate * regen = NEW AStandardRegenerate(0, card, card, regenCost); + regenerations[card] = regen; + game->addObserver(regen); + } + return 1; + } + + int removed(MTGCardInstance * card){ + card->power -= power; + card->addToToughness(-toughness); + if (ability != -1 && card->basicAbilities[ability]) card->basicAbilities[ability] -=1; + if (regenCost){ + if(regenerations.find(card) != regenerations.end()){ + if (game->isInPlay(card)) game->removeObserver(regenerations[card]); + regenerations.erase(card); + } + } + return 1; + } + +}; + +//Lords (Merfolk lord...) give power and toughness to OTHER creatures of a given color, they can give them special abilities, regeneration +class AColorLord:public ListMaintainerAbility{ + public: + int color; + int notcolor; + int power, toughness; + int ability; + ManaCost * regenCost; + map regenerations; + AColorLord(int _id, MTGCardInstance * card, int _color, int _notcolor = -1, int _power = 0 , int _toughness = 0, int _ability = -1, ManaCost * _regenCost = NULL):ListMaintainerAbility(_id,card){ + color = _color; + notcolor = _notcolor; + power = _power; + toughness = _toughness; + ability = _ability; + regenCost = _regenCost; + } + + int canBeInList(MTGCardInstance * card){ + if (notcolor > -1){ + if (card!=source && card->isACreature() && !card->hasColor(color)) return 1; + }else{ + if (card!=source && card->isACreature() && card->hasColor(color)) return 1; + } + return 0; + } + + int added(MTGCardInstance * card){ + card->power += power; + card->addToToughness(toughness); + if (ability != -1) card->basicAbilities[ability] +=1; + if (regenCost){ + AStandardRegenerate * regen = NEW AStandardRegenerate(0, card, card, regenCost); + regenerations[card] = regen; + game->addObserver(regen); + } + return 1; + } + + int removed(MTGCardInstance * card){ + card->power -= power; + card->addToToughness(-toughness); + if (ability != -1 && card->basicAbilities[ability]) card->basicAbilities[ability] -=1; + if (regenCost){ + if(regenerations.find(card) != regenerations.end()){ + game->removeObserver(regenerations[card]); + regenerations.erase(card); + } + } + return 1; + } + +}; + + +/* Standard Damager, can choose a NEW target each time the price is paid */ +class ADamager:public TargetAbility{ + public: + int damage; + ADamager(int id, MTGCardInstance * card, ManaCost * _cost, int _damage, TargetChooser * _tc = NULL, int _tap = 1):TargetAbility(id,card, _tc, _cost,0,_tap),damage(_damage){ + if (!tc) tc = NEW DamageableTargetChooser(card); + } + int resolve(){ + Damageable * _target = tc->getNextDamageableTarget(); + GameObserver::GetInstance()->mLayers->stackLayer()->addDamage(source,_target, damage); + return 1; + } + + +}; + +/* Can tap a target for a cost */ +class ATapper:public TargetAbility{ + public: + int damage; + ATapper(int id, MTGCardInstance * card, ManaCost * _cost, TargetChooser * _chooser):TargetAbility(id,card, _chooser, _cost){ + } + + int resolve(){ + MTGCardInstance * _target = tc->getNextCardTarget(); + if (_target){ + _target->tapped = true; + } + return 1; + } + +}; + +// Add life of gives damage if a given zone has more or less than [condition] cards at the beginning of [phase] +//Ex : the rack, ivory tower... +class ALifeZoneLink:public MTGAbility{ + public: + int phase; + int condition; + int life; + int controller; + int nbcards; + MTGGameZone * zone; + ALifeZoneLink(int _id ,MTGCardInstance * card, int _phase, int _condition, int _life = -1, int _controller = 0, MTGGameZone * _zone = NULL):MTGAbility(_id, card){ + phase = _phase; + condition = _condition; + controller = _controller; + life = _life; + zone = _zone; + if (zone == NULL){ + if (controller){ + zone = game->currentPlayer->game->hand; + }else{ + zone = game->opponent()->game->hand; + } + } + } + + void Update(float dt){ + if (newPhase != currentPhase && newPhase == phase){ + if ((controller && game->currentPlayer == source->controller()) ||(!controller && game->currentPlayer != source->controller()) ){ + if ((condition < 0 && zone->nb_cards < - condition) ||(condition >0 && zone->nb_cards > condition)){ + int diff = zone->nb_cards - condition; + if (condition < 0) diff = - condition - zone->nb_cards; + if (life > 0){ + game->currentPlayer->life+=life*diff; + }else{ + game->mLayers->stackLayer()->addDamage(source,game->currentPlayer,-life*diff); + } + } + } + } + } +}; + +//Creatures that cannot attack if opponent has not a given type of land, and die if controller has not this type of land +//Ex : pirate ship... +class AStrongLandLinkCreature: public MTGAbility{ + public: + char land[20]; + AStrongLandLinkCreature(int _id, MTGCardInstance * _source, const char * _land):MTGAbility(_id, _source){ + sprintf(land,"%s",_land); + } + + void Update(float dt){ + if (source->isAttacker()){ + if (!game->opponent()->game->inPlay->hasType(land)){ + source->attacker=0; + source->tapped = 0; + //TODO Improve, there can be race conditions here + } + } + Player * player = source->controller(); + if(!player->game->inPlay->hasType(land)){ + player->game->putInGraveyard(source); + } + } +}; + +//Steal control of a target +class AControlStealAura: public MTGAbility{ + public: + Player * originalController; + AControlStealAura(int _id , MTGCardInstance * _source, MTGCardInstance * _target):MTGAbility(_id, _source, _target){ + originalController = _target->controller(); + _target->changeController(game->currentlyActing()); + } + + int destroy(){ + MTGCardInstance * _target = (MTGCardInstance *) target; + if (_target->controller()->game->inPlay->hasCard(_target)){ //if the target is still in game -> spell was destroyed + _target->changeController(originalController); + } + return 1; + } + //TODO put it back into owners's graveyard if needed... +}; + +//Ability to untap a target +class AUntaper:public TargetAbility{ + public: + AUntaper(int _id, MTGCardInstance * card, ManaCost * _manacost, TargetChooser * _tc):TargetAbility(_id,card,_tc,_manacost){ + } + + int resolve(){ + tc->getNextCardTarget()->tapped = 0; + return 1; + } + +}; + + +//Same as StealControl Aura ???? Obsolete ? +class ATakeControlAura:public MTGAbility{ + public: + Player * previousController; + ATakeControlAura(int _id, MTGCardInstance * _source, MTGCardInstance * _target):MTGAbility(_id, _source,_target){ + previousController = _target->controller(); + previousController->game->putInZone(_target, previousController->game->inPlay, source->controller()->game->inPlay); + + } + + int destroy(){ + MTGCardInstance * _target = (MTGCardInstance *) target; + if (_target->controller()->game->inPlay->hasCard(_target)){ + _target->controller()->game->putInZone(_target, _target->controller()->game->inPlay, previousController->game->inPlay); + } + return 1; + } + +}; + +//Creatures that kill their blockers +//Ex : Cockatrice +class AOldSchoolDeathtouch:public MTGAbility{ + public: + MTGCardInstance * opponents[20]; + int nbOpponents; + AOldSchoolDeathtouch(int _id, MTGCardInstance * _source):MTGAbility(_id, _source){ + nbOpponents = 0; + } + + void Update(float dt){ + if (newPhase != currentPhase){ + if( newPhase == MTG_PHASE_COMBATDAMAGE){ + nbOpponents = 0; + MTGCardInstance * opponent = source->getNextOpponent(); + while (opponent && !opponent->hasSubtype("wall")){ + opponents[nbOpponents] = opponent; + nbOpponents ++; + opponent = source->getNextOpponent(opponent); + } + }else if (newPhase == MTG_PHASE_COMBATEND){ + for (int i = 0; i < nbOpponents ; i++){ + game->mLayers->stackLayer()->addPutInGraveyard(opponents[i]); + } + } + } + } + + int testDestroy(){ + if(!game->isInPlay(source) && currentPhase != MTG_PHASE_UNTAP){ + return 0; + }else{ + return MTGAbility::testDestroy(); + } + } +}; + + +//Converts a card to a creature (Aura) +class AConvertToCreatureAura:public MTGAbility{ + public: + AConvertToCreatureAura(int _id, MTGCardInstance * _source, MTGCardInstance * _target, int _power, int _toughness):MTGAbility(_id, _source, _target){ + _target->setSubtype("creature"); + _target->power = _power; + _target->toughness = _toughness; + _target->life = _toughness; + //_target->afterDamage(); + _target->doDamageTest = 1; + } + + int destroy(){ + MTGCardInstance * _target = (MTGCardInstance *) target; + _target->removeType("creature"); + return 1; + } +}; + +/* + Specific Classes +*/ + +// 1092 Specific to Aladdin's Lamp +class AAladdinsLamp: public TargetAbility{ + public: + CardDisplay cd; + int nbcards; + int init; + AAladdinsLamp(int _id, MTGCardInstance * card):TargetAbility(_id,card){ + cost = NEW ManaCost(); + cost->x(); + cd = CardDisplay(1,game,SCREEN_WIDTH/2, SCREEN_HEIGHT/2,NULL); + MTGGameZone * zones[] = {game->currentPlayer->game->library}; + tc = NEW TargetZoneChooser(zones,1,source); + nbcards = 0; + init = 0; + } + + void Update(float dt){ + if (waitingForAnswer){ + if (!init){ + cd.resetObjects(); + int wished = game->currentlyActing()->getManaPool()->getConvertedCost(); + game->currentlyActing()->getManaPool()->pay(cost); + nbcards = 0; + MTGGameZone * library = game->currentlyActing()->game->library; + while (nbcards < wished && nbcards < library->nb_cards){ + cd.AddCard(library->cards[library->nb_cards - 1 - nbcards]); + nbcards++; + } + init = 1; + } + cd.Update(dt); + cd.CheckUserInput(dt); + } + } + + void Render(float dt){ + if (waitingForAnswer){ + cd.Render(); + } + } + + + int fireAbility(){ + source->tapped = 1; + MTGLibrary * library = game->currentlyActing()->game->library; + library->removeCard(tc->getNextCardTarget()); + library->shuffleTopToBottom(nbcards - 1 ); + library->addCard(tc->getNextCardTarget()); + init = 0; + return 1; + } + + int resolve(){return 1;}; + + +}; + + + + +//Ankh of Mishra +class AAnkhOfMishra: public MTGAbility{ + public: + int playerLands[2]; + AAnkhOfMishra(int id, MTGCardInstance * _source):MTGAbility(id, _source){ + for (int i=0; i< 2; i++){ + playerLands[i] = GameObserver::GetInstance()->players[i]->game->inPlay->countByType("land"); + } + } + + void Update(float dt){ + for (int i=0; i < 2; i++){ + int lands = GameObserver::GetInstance()->players[i]->game->inPlay->countByType("land"); + while (lands > playerLands[i]){ + GameObserver::GetInstance()->mLayers->stackLayer()->addDamage(source,GameObserver::GetInstance()->players[i], 2); + playerLands[i]++; + } + } + } +}; + + + +// Armageddon Clock +class AArmageddonClock:public MTGAbility{ + public: + int counters; + ManaCost cost; + AArmageddonClock(int id, MTGCardInstance * _source):MTGAbility(id, _source){ + counters = 0; + int _cost[] = {MTG_COLOR_ARTIFACT, 4}; + cost = ManaCost(_cost,1); + } + + void Update(float dt){ + if (newPhase != currentPhase){ + if (newPhase == MTG_PHASE_UPKEEP && game->currentPlayer->game->inPlay->hasCard(source)){ + counters ++; + }else if (newPhase == MTG_PHASE_DRAW && counters > 0 && game->currentPlayer->game->inPlay->hasCard(source)){ //End of upkeep = beginning of draw + GameObserver::GetInstance()->mLayers->stackLayer()->addDamage(source,GameObserver::GetInstance()->players[0], counters); + GameObserver::GetInstance()->mLayers->stackLayer()->addDamage(source,GameObserver::GetInstance()->players[1], counters); + } + } + } + int isReactingToClick(MTGCardInstance * _card){ + if (counters > 0 && _card == source && currentPhase == MTG_PHASE_UPKEEP){ + if (game->currentlyActing()->getManaPool()->canAfford( & cost)){ + return 1; + } + } + return 0; + } + + int reactToClick(MTGCardInstance * _card){ + if (!isReactingToClick( _card)) return 0; + game->currentlyActing()->getManaPool()->pay(& cost); + counters --; + return 1; + } +}; + + +//Black Vise +class ABlackVise: public MTGAbility{ + public: + int nbcards; + ABlackVise(int id, MTGCardInstance * _source):MTGAbility(id, _source){ + nbcards = game->opponent()->game->hand->nb_cards; + } + + void Update(float dt){ + if (newPhase == MTG_PHASE_UPKEEP && GameObserver::GetInstance()->opponent()->game->inPlay->hasCard(source)){ + nbcards = game->currentPlayer->game->hand->nb_cards; + } + if (newPhase != currentPhase && newPhase == MTG_PHASE_DRAW && GameObserver::GetInstance()->opponent()->game->inPlay->hasCard(source)){ + if ( nbcards > 4) game->mLayers->stackLayer()->addDamage(source,game->currentPlayer, nbcards - 4); + } + } +}; + + +//Channel +class AChannel:public ActivatedAbility{ + public: + + AChannel(int _id, MTGCardInstance * card):ActivatedAbility(_id, card,0,0,0){ + } + + int isReactingToClick(PlayGuiObject * object){ + if (object->type == GUI_AVATAR){ + Player * player = ((GuiAvatar *)object)->player; + if (player == source->controller()) return 1; + } + return 0; + } + + int resolve(){ + source->controller()->life--; + source->controller()->getManaPool()->add(MTG_COLOR_ARTIFACT, 1); + return 1; + } + + int testDestroy(){ + if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP) return 1; + currentPhase = newPhase; + return 0; + } +}; + + +// Clockwork Beast +class AClockworkBeast:public MTGAbility{ + public: + int counters; + ManaCost cost; + AClockworkBeast(int id, MTGCardInstance * _source):MTGAbility(id, _source){ + counters = 7; + ((MTGCardInstance *)target)->power+=7; + int _cost[] = {MTG_COLOR_ARTIFACT, 1}; + cost = ManaCost(_cost,1); + } + + void Update(float dt){ + if (newPhase != currentPhase && newPhase == MTG_PHASE_COMBATEND){ + if (((MTGCardInstance *)source)->isAttacker() || ((MTGCardInstance *)source)->isDefenser()){ + counters--; + ((MTGCardInstance *)target)->power-=1; + } + } + } + int isReactingToClick(MTGCardInstance * _card){ + if (counters < 7 && _card == source && currentPhase == MTG_PHASE_UPKEEP && game->currentPlayer->game->inPlay->hasCard(source)){ + if (game->currentlyActing()->getManaPool()->canAfford( & cost)){ + return 1; + } + } + return 0; + } + + int reactToClick(MTGCardInstance * _card){ + if (!isReactingToClick( _card)) return 0; + game->currentlyActing()->getManaPool()->pay(& cost); + counters ++; + ((MTGCardInstance *)target)->power++; + ((MTGCardInstance *)target)->tapped = 1; + return 1; + } +}; + +//1102: Conservator +class AConservator: public MTGAbility{ + public: + int canprevent; + ManaCost cost; + AConservator(int _id, MTGCardInstance * _source):MTGAbility(_id, _source){ + canprevent = 0; + int _cost[] = {MTG_COLOR_ARTIFACT, 2}; + cost = ManaCost(_cost, 1); + } + + int alterDamage(Damage * damage){ + if (canprevent && damage->target == source->controller()){ + if (damage->damage >= canprevent){ + damage->damage-=canprevent; + canprevent = 0; + }else{ + canprevent-=damage->damage; + damage->damage = 0; + } + } + return 1; + } + int alterDamage(){ + if (canprevent){ + ActionStack * stack = game->mLayers->stackLayer(); + for (int i = stack->mCount-1; i>=0; i--){ + if (!canprevent) return 1; + Interruptible * current = ((Interruptible *)stack->mObjects[i]); + if (current->type == ACTION_DAMAGE && current->state==NOT_RESOLVED){ + Damage * damage = (Damage *)current; + alterDamage(damage); + }else if (current->type == ACTION_DAMAGES && current->state == NOT_RESOLVED){ + DamageStack * damages = (DamageStack *)current; + for (int j = damages->mCount-1;j >=0; j--){ + alterDamage(((Damage *)damages->mObjects[j])); + } + } + } + } + return 1; + } + + void Update(float dt){ + alterDamage(); + } + + int isReactingToClick(MTGCardInstance * _card){ + if ( _card == source && game->currentlyActing()->game->inPlay->hasCard(source) && !_card->isTapped()){ + if (game->currentlyActing()->getManaPool()->canAfford( & cost)){ + return 1; + } + } + return 0; + } + + int reactToClick(MTGCardInstance * _card){ + if (!isReactingToClick( _card)) return 0; + game->currentlyActing()->getManaPool()->pay(& cost); + source->tapped = 1; + canprevent = 2; + alterDamage(); + return 1; + } + +}; + + +//Creature bond +class ACreatureBond:public TriggeredAbility{ + public: + int resolved; + ACreatureBond(int _id, MTGCardInstance * _source, MTGCardInstance * _target):TriggeredAbility(_id,_source,_target){ + resolved = 1; + } + + int trigger(){ + MTGCardInstance * _target = (MTGCardInstance *) target; + for (int i = 0; i < 2; i++){ + if (game->players[i]->game->graveyard->hasCard(_target)) return 1; + } + return 0; + } + + int resolve(){ + MTGCardInstance * _target = (MTGCardInstance *) target; + game->mLayers->stackLayer()->addDamage(source,_target->controller(),_target->toughness); + resolved = 1; + return 1; + } + + int testDestroy(){ + MTGCardInstance * _target = (MTGCardInstance *)target; + if(_target->controller()->game->graveyard->hasCard(_target) && !resolved){ + return 0; + }else{ + return TriggeredAbility::testDestroy(); + } + } +}; + +//1105: Dingus Egg +class ADingusEgg: public MTGAbility{ + public: + int playerLands[2]; + ADingusEgg(int id, MTGCardInstance * _source):MTGAbility(id, _source){ + for (int i=0; i< 2; i++){ + playerLands[i] = GameObserver::GetInstance()->players[i]->game->inPlay->countByType("land"); + } + } + + void Update(float dt){ + for (int i=0; i < 2; i++){ + int lands = GameObserver::GetInstance()->players[i]->game->inPlay->countByType("land"); + while (lands < playerLands[i]){ + GameObserver::GetInstance()->mLayers->stackLayer()->addDamage(source,GameObserver::GetInstance()->players[i], 2); + playerLands[i]--; + } + } + } +}; + + + +//1106 DisruptingScepter +class ADisruptingScepter:public TargetAbility{ + public: + ADisruptingScepter(int id, MTGCardInstance * _source):TargetAbility(id,_source){ + MTGGameZone * zones[] = {GameObserver::GetInstance()->opponent()->game->hand}; + tc = NEW TargetZoneChooser(zones,1,_source); + int _cost[] = {MTG_COLOR_ARTIFACT, 3}; + cost = NEW ManaCost(_cost,1); + } + + void Update(float dt){ + if (game->opponent()->isAI()){ + if(waitingForAnswer){ + MTGCardInstance * card = ((AIPlayer *)game->opponent())->chooseCard(tc, source); + if (card) tc->toggleTarget(card); + if (!card || tc->targetsReadyCheck() == TARGET_OK) waitingForAnswer = 0; + } + TargetAbility::Update(dt); + }else{ + TargetAbility::Update(dt); + } + } + + int resolve(){ + game->opponent()->game->putInGraveyard(tc->getNextCardTarget()); + return 1; + } + + +}; + + +//1108 Ebony Horse +class AEbonyHorse:public TargetAbility{ + public: + + AEbonyHorse(int _id, MTGCardInstance * _source):TargetAbility(_id,_source, NEW CreatureTargetChooser()){ + int _cost[] = {MTG_COLOR_ARTIFACT, 2}; + cost = NEW ManaCost(_cost,1); + } + + int resolve(){ + tc->getNextCardTarget()->attacker = 0; + return 1; + } + +}; + +//1345 Farmstead +class AFarmstead:public ActivatedAbility{ + public: + AFarmstead(int _id, MTGCardInstance * source, MTGCardInstance * _target):ActivatedAbility(_id, source,0,1,0){ + int _cost[] = {MTG_COLOR_WHITE, 2}; + cost = NEW ManaCost(_cost,1); + target = _target; + } + + int isReactingToClick(MTGCardInstance * card){ + if (!ActivatedAbility::isReactingToClick(card)) return 0; + if (currentPhase == MTG_PHASE_UPKEEP) return 1; + return 0; + } + + int resolve(){ + source->controller()->life++; + return 1; + } + +}; + +//1110 Glasses of Urza +class AGlassesOfUrza:public MTGAbility{ + public: + CardDisplay * display; + AGlassesOfUrza(int _id, MTGCardInstance * _source):MTGAbility(_id, _source){ + display = NEW CardDisplay(0, game,SCREEN_WIDTH/2, SCREEN_HEIGHT/2,NULL); + } + + void Update(float dt){ + if(modal){ + display->Update(dt); + } + } + + void CheckUserInput(float dt){ + if (modal){ + display->CheckUserInput(dt); + JGE * mEngine = JGE::GetInstance(); + if (mEngine->GetButtonClick(PSP_CTRL_CROSS)){ + modal = 0; + } + } + } + + void Render(float dt){ + if (modal){ + display->Render(); + } + + } + int isReactingToClick(MTGCardInstance * card){ + if ( card == source){ + if (game->currentlyActing()->game->isInPlay(card) && !source->isTapped()){ + return 1; + } + } + return 0; + } + + int reactToClick(MTGCardInstance * card){ + if (!isReactingToClick(card)) return 0; + source->tapped = 1; + modal = 1; + return 1; + } + +}; + +//1112 Howling Mine +class AHowlingMine:public MTGAbility{ + public: + AHowlingMine(int _id, MTGCardInstance * _source):MTGAbility(_id, _source){} + + void Update(float dt){ + if (newPhase != currentPhase && newPhase == MTG_PHASE_DRAW && !source->tapped){ + game->mLayers->stackLayer()->addDraw(game->currentPlayer); + } + } +}; + +//1119 Jayemdae Tome +class AJayemdaeTome:public ActivatedAbility{ + public: + AJayemdaeTome(int _id, MTGCardInstance * card):ActivatedAbility(_id, card){ + int _cost[] = {MTG_COLOR_ARTIFACT, 4}; + cost = NEW ManaCost(_cost,1); + } + + int resolve(){ + game->mLayers->stackLayer()->addDraw(source->controller()); + return 1; + } +}; + + +//Living Artifact +class ALivingArtifact:public MTGAbility{ + public: + int usedThisTurn; + int counters; + Damage * latest; + ALivingArtifact(int _id, MTGCardInstance * _source, MTGCardInstance * _target):MTGAbility(_id,_source,_target){ + usedThisTurn = 0; + counters = 0; + latest = NULL; + } + + void Update(float dt){ + if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP) usedThisTurn = 0; + Damage * damage = ((Damage *)game->mLayers->stackLayer()->getNext(latest,ACTION_DAMAGE,RESOLVED_OK)); + while (damage){ + if (damage->target == source->controller()){ + counters += damage->damage; + } + latest = damage; + damage = ((Damage *)game->mLayers->stackLayer()->getNext(damage,ACTION_DAMAGE,RESOLVED_OK)); + } + } + + int isReactingtoclick(MTGCardInstance * card){ + if (currentPhase == MTG_PHASE_UPKEEP && card == source && game->currentPlayer == source->controller() && counters && !usedThisTurn){ + return 1; + } + return 0; + } + + int reactToClick(MTGCardInstance * card){ + source->controller()->life+=1; + counters--; + usedThisTurn = 1; + return 1; + } + +}; + +//Lord of the Pit +class ALordOfThePit: public TargetAbility{ + public: + int paidThisTurn; + ALordOfThePit(int _id, MTGCardInstance * source):TargetAbility(_id, source, NEW CreatureTargetChooser(),0,1,0){ + paidThisTurn = 1; + } + + void Update(float dt){ + if (newPhase != currentPhase && source->controller() == game->currentPlayer){ + if (newPhase == MTG_PHASE_UNTAP){ + paidThisTurn = 0; + }else if( newPhase == MTG_PHASE_UPKEEP + 1 && !paidThisTurn){ + game->mLayers->stackLayer()->addDamage(source,source->controller(), 7); + } + } + TargetAbility::Update(dt); + } + + int isReactingToClick(MTGCardInstance * card){ + if (currentPhase != MTG_PHASE_UPKEEP || paidThisTurn) return 0; + return TargetAbility::isReactingToClick(card); + } + + int resolve(){ + MTGCardInstance * card = tc->getNextCardTarget(); + if (card && card != source && card->controller() == source->controller()){ + card->controller()->game->putInGraveyard(card); + paidThisTurn = 1; + return 1; + } + return 0; + } + +}; +//1143 Animate Dead +class AAnimateDead:public MTGAbility{ + public: + AAnimateDead(int _id, MTGCardInstance * _source, MTGCardInstance * _target):MTGAbility(_id, _source, _target){ + MTGCardInstance * card = _target; + card->power--; + card->life = card->toughness; + //Put the card in play again, with all its abilities ! + //AbilityFactory af; + Spell * spell = NEW Spell(card); + //af.addAbilities(game->mLayers->actionLayer()->getMaxId(), spell); + source->controller()->game->putInZone(card, _target->controller()->game->graveyard, source->controller()->game->stack); + spell->resolve(); + delete spell; + } + + int destroy(){ + MTGCardInstance * card = (MTGCardInstance *) target; + card->power++; + return 1; + } +}; + +//1144 Bad Moon, 1341 Crusade +class ABadMoon:public ListMaintainerAbility{ + public: + int color; + ABadMoon(int _id, MTGCardInstance * _source, int _color = MTG_COLOR_BLACK):ListMaintainerAbility(_id, _source),color(_color){ + } + + int canBeInList(MTGCardInstance * card){ + if (card->isACreature() && card->hasColor(color)) return 1; + return 0; + } + + int added(MTGCardInstance * card){ + card->power += 1; + card->addToToughness(1); + return 1; + } + + int removed(MTGCardInstance * card){ + card->power -= 1; + card->addToToughness(-1); + return 1; + } + +}; + + +//1159 Erg Raiders +class AErgRaiders:public MTGAbility{ + public: + int init; + int dealDamage; + AErgRaiders(int _id, MTGCardInstance * _source):MTGAbility(_id, _source){ + init = 0; + dealDamage = 0; + } + + void Update(float dt){ + if (newPhase != currentPhase){ + Player * controller = source->controller(); + if (newPhase == MTG_PHASE_COMBATDAMAGE && game->currentPlayer == controller){ + if (!source->isAttacker() && init){ + dealDamage = 1; + } + }else if (newPhase == MTG_PHASE_UNTAP && game->currentPlayer != controller){ + if (dealDamage){ + game->mLayers->stackLayer()->addDamage(source, controller,2); + } + init = 1; + dealDamage = 0; + } + } + + } +}; + +//Fastbond +class AFastbond:public TriggeredAbility{ + public: + int alreadyPlayedALand; + AFastbond(int _id, MTGCardInstance * card):TriggeredAbility(_id, card){ + alreadyPlayedALand = 0; + } + + void Update(float dt){ + if (newPhase!=currentPhase && newPhase == MTG_PHASE_UNTAP){ + alreadyPlayedALand = 0; + } + TriggeredAbility::Update(dt); + } + + int trigger(){ + if(source->controller()->canPutLandsIntoPlay==0) return 1; + return 0; + } + + int resolve(){ + source->controller()->canPutLandsIntoPlay = 1; + if (alreadyPlayedALand){ + game->mLayers->stackLayer()->addDamage(source, source->controller(), 1); + } + alreadyPlayedALand = 1; + return 1; + } +}; + + + +//1165 Hypnotic Specter +class AHypnoticSpecter:public MTGAbility{ + public: + int nbdamagesthisturn[2]; + AHypnoticSpecter(int _id, MTGCardInstance * _source):MTGAbility(_id, _source){ + currentPhase = -1; + for (int i = 0; i < 2; i++){ + nbdamagesthisturn[i] = 0; + } + } + + void Update(float dt){ + if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP){ + for (int i = 0; i < 2; i++){ + nbdamagesthisturn[i] = 0; + } + } + + ActionStack * as = game->mLayers->stackLayer(); + int nbdamages[2]; + for (int i = 0; i < 2; i++){ + nbdamages[i] = 0; + } + + Damage * current = ((Damage *)as->getNext(NULL,ACTION_DAMAGE,RESOLVED_OK)); + while(current){ + if (current->source == source){ + for (int j=0; j < 2; j++){ + if(current->target == game->players[j]) nbdamages[j]++; + } + } + current = ((Damage *)as->getNext(current,ACTION_DAMAGE,RESOLVED_OK)); + + } + + for (int i = 0; i < 2; i++){ + while(nbdamages[i] > nbdamagesthisturn[i]){ + nbdamagesthisturn[i]++; + game->players[i]->game->discardRandom(game->players[i]->game->hand); + } + } + + + } + +}; + +//1117 Jandor's Ring +class AJandorsRing:public ActivatedAbility{ + public: + AJandorsRing(int _id, MTGCardInstance * _source):ActivatedAbility(_id,_source, NEW ManaCost()){ + cost->add(MTG_COLOR_ARTIFACT, 2); + } + + int isReactingToClick(MTGCardInstance * card){ + if (!source->controller()->game->hand->hasCard(source->controller()->game->library->lastCardDrawn)) return 0; + return ActivatedAbility::isReactingToClick(card); + } + + int resolve(){ + source->controller()->game->putInGraveyard(source->controller()->game->library->lastCardDrawn); + game->mLayers->stackLayer()->addDraw(source->controller()); + return 1; + } + +}; + + +//Kudzu. +//What happens when there are no targets ??? +class AKudzu: public TargetAbility{ + public: + int previouslyTapped; + AKudzu(int _id, MTGCardInstance * card, MTGCardInstance * _target):TargetAbility(_id,card, NEW TypeTargetChooser("land",card)){ + tc->toggleTarget(_target); + target = _target; + previouslyTapped = 0; + if (_target->tapped) previouslyTapped = 1; + } + + + void Update(float dt){ + MTGCardInstance * _target = (MTGCardInstance *)target; + if (!_target->tapped){ + previouslyTapped = 0; + }else if (!previouslyTapped){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("Kudzu Strikes !\n"); +#endif + MTGCardInstance * _target = (MTGCardInstance *)target; + _target->controller()->game->putInGraveyard(_target); + reactToClick(source); // ???? + } + TargetAbility::Update(dt); + } + + int isReactingToClick(MTGCardInstance * card){ + MTGCardInstance * _target = (MTGCardInstance *)target; + if (card == source && (!_target || !_target->isInPlay())){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("Kudzu Reacts to click !\n"); +#endif + return 1; + } + return 0; + } + + /* + int reactToClick(MTGCardInstance * card){ + if (!waitingForAnswer) { + }else{ + tc->toggleTarget(card); + } + return 1; + } + */ + + int resolve(){ + target = tc->getNextCardTarget(); + source->target = (MTGCardInstance *) target; + previouslyTapped = 0; + if (source->target->tapped) previouslyTapped = 1; + return 1; + } + + int testDestroy(){ + GameObserver * g = GameObserver::GetInstance(); + int stillLandsInPlay = 0; + for (int i = 0; i < 2; i++){ + if (game->players[i]->game->inPlay->hasType("land")) stillLandsInPlay = 1; + } + if (!stillLandsInPlay){ + source->controller()->game->putInGraveyard(source); + return 1; + } + + if (!game->isInPlay(source)){ + return 1; + } + + return 0; + } + + +}; + +//Millstone +class AMillstone:public TargetAbility{ + public: + AMillstone(int _id, MTGCardInstance * card):TargetAbility(_id,card, NEW PlayerTargetChooser(), NEW ManaCost()){ + cost->add(MTG_COLOR_ARTIFACT, 2); + } + + int resolve(){ + Player * player = tc->getNextPlayerTarget(); + if (!player) return 0; + MTGLibrary * library = player->game->library; + for (int i = 0; i < 2; i++){ + if (library->nb_cards) + player->game->putInZone(library->cards[library->nb_cards-1],library, player->game->graveyard); + } + return 1; + } + +}; + +//1170: Nightmare +class ANightmare:public ListMaintainerAbility{ + public: + ANightmare(int _id, MTGCardInstance * _source):ListMaintainerAbility(_id, _source){ + } + + int canBeInList(MTGCardInstance * card){ + if (source->controller()->game->inPlay->hasCard(card) && card->hasType("swamp") ) return 1; + return 0; + } + + int added(MTGCardInstance * card){ + source->power += 1; + source->addToToughness(1); + return 1; + } + + int removed(MTGCardInstance * card){ + source->power -= 1; + source->addToToughness(-1); + return 1; + } + +}; + + + +//1172 Pestilence +class APestilence: public ActivatedAbility{ + public: + APestilence(int _id, MTGCardInstance * card):ActivatedAbility(_id, card, NEW ManaCost(), 0,0){ + cost->add(MTG_COLOR_BLACK, 1); + } + + void Update(float dt){ + if (newPhase !=currentPhase && newPhase == MTG_PHASE_EOT){ + if (!game->players[0]->game->inPlay->hasType("creature") && !game->players[1]->game->inPlay->hasType("creature")){ + source->controller()->game->putInGraveyard(source); + } + } + } + + int resolve(){ + for (int i = 0; i < 2 ; i++){ + MTGInPlay * inplay = game->players[i]->game->inPlay; + for (int j = inplay->nb_cards - 1 ; j >=0; j--){ + if (inplay->cards[j]->isACreature()) game->mLayers->stackLayer()->addDamage(source,inplay->cards[j],1); + } + game->mLayers->stackLayer()->addDamage(source,game->players[i],1); + } + return 1; + } + +}; + +//Plague Rats and similar. Power and toughness equal to number of cards that share a name +class APlagueRats:public ListMaintainerAbility{ + public: + string name; + APlagueRats(int _id, MTGCardInstance * _source, const char * _name):ListMaintainerAbility(_id,_source){ + name = _name; + std::transform(name.begin(), name.end(), name.begin(),::tolower ); + } + + int canBeInList(MTGCardInstance * card){ + if (card == source) return 0; + string compared = card->name; + std::transform( compared.begin(), compared.end(), compared.begin(),::tolower ); + if (name.compare(compared) == 0) return 1; + return 0; + } + + int added(MTGCardInstance * card){ + source->power += 1; + source->addToToughness(1); + return 1; + } + + int removed(MTGCardInstance * card){ + source->power -= 1; + source->addToToughness(-1); + return 1; + } + +}; + +//Power Leak +class APowerLeak:public TriggeredAbility{ + public: + int damagesToDealThisTurn; + ManaCost cost; + APowerLeak(int _id, MTGCardInstance * _source, MTGCardInstance * _target):TriggeredAbility(_id, _source, _target){ + cost.add(MTG_COLOR_ARTIFACT, 1); + damagesToDealThisTurn = 0; + } + + void Update(float dt){ + MTGCardInstance * _target = (MTGCardInstance *) target; + if (newPhase != currentPhase && newPhase == MTG_PHASE_UPKEEP && _target->controller() == game->currentPlayer){ + damagesToDealThisTurn = 2; + } + TriggeredAbility::Update(dt); + } + + int isReactingToClick(MTGCardInstance * card){ + MTGCardInstance * _target = (MTGCardInstance *) target; + if (damagesToDealThisTurn && currentPhase == MTG_PHASE_UPKEEP && card==source && _target->controller() == game->currentPlayer){ + if (game->currentPlayer->getManaPool()->canAfford(& cost)) return 1; + } + return 0; + } + + int reactToclick(MTGCardInstance * card){ + game->currentPlayer->getManaPool()->pay( & cost); + damagesToDealThisTurn--; + return 1; + } + + int trigger(){ + MTGCardInstance * _target = (MTGCardInstance *) target; + if (newPhase != currentPhase && newPhase == MTG_PHASE_DRAW && _target->controller() == game->currentPlayer){ + if (damagesToDealThisTurn) return 1; + } + return 0; + } + + int resolve(){ + MTGCardInstance * _target = (MTGCardInstance *) target; + game->mLayers->stackLayer()->addDamage(source,_target->controller(), damagesToDealThisTurn); + return 1; + } +}; + +//Power Surge +class APowerSurge:public TriggeredAbility{ + public: + int totalLands; + APowerSurge(int _id, MTGCardInstance * _source):TriggeredAbility(_id,_source){ + totalLands = 0; + } + + int trigger(){ + if (newPhase != currentPhase && newPhase == MTG_PHASE_EOT){ + //That's ugly but untapped land at the beginning of the turn are opponent's untapped lands at the end of the turn + totalLands = 0; + MTGInPlay * inPlay = game->opponent()->game->inPlay; + for (int i = 0; i < inPlay->nb_cards; i++){ + MTGCardInstance * card = inPlay->cards[i]; + if (!card->tapped && card->hasType("land")){ + totalLands++; + } + } + } + if (newPhase != currentPhase && newPhase == MTG_PHASE_UPKEEP && totalLands){ + return 1; + } + return 0; + } + + int resolve(){ + if (totalLands) game->mLayers->stackLayer()->addDamage(source,game->currentPlayer,totalLands); + totalLands = 0; + return 1; + } +}; + +//1175 Royal Assassin +class ARoyalAssassin:public TargetAbility{ + public: + + ARoyalAssassin(int _id, MTGCardInstance * _source):TargetAbility(_id,_source, NEW CreatureTargetChooser()){ + } + + int resolve(){ + MTGCardInstance * _target = tc->getNextCardTarget(); + if(_target && _target->tapped){ + _target->controller()->game->putInGraveyard(_target); + return 1; + } + return 0; + } + +}; + + +//1176 Sacrifice +class ASacrifice:public InstantAbility{ + public: + ASacrifice(int _id, MTGCardInstance * _source, MTGCardInstance * _target):InstantAbility(_id, _source){ + target = _target; + } + + int resolve(){ + MTGCardInstance * _target = (MTGCardInstance *) target; + if (_target->isInPlay()){ + game->currentlyActing()->game->putInGraveyard(_target); + int x = _target->getManaCost()->getConvertedCost(); + game->currentlyActing()->getManaPool()->add(MTG_COLOR_BLACK, x); + } + return 1; + } + +}; + +//1178 Scavenging Ghoul +class AScavengingGhoul:public MTGAbility{ + public: + int counters; + AScavengingGhoul(int _id, MTGCardInstance * _source, MTGCardInstance * _target):MTGAbility(_id, _source, _target){ + counters = 0; + } + + + void Update(float dt){ + //TODO + } + + int isReactingToClick(MTGCardInstance * _card){ + if (counters > 0 && _card == source && game->currentlyActing()->game->inPlay->hasCard(source)){ + return 1; + } + return 0; + } + + int reactToClick(MTGCardInstance * _card){ + if (!isReactingToClick( _card)) return 0; + counters--; + source->regenerate(); + return 1; + } + +}; + +//1218 Psychic Venom +class APsychicVenom:public MTGAbility{ + public: + int tapped; + APsychicVenom(int _id, MTGCardInstance * _source, MTGCardInstance * _target):MTGAbility(_id, _source,_target){ + tapped = _target->tapped; + } + + void Update(float dt){ + MTGCardInstance* _target = (MTGCardInstance* )target; + int newState = _target->isTapped(); + if (newState != tapped && newState == 1){ + game->mLayers->stackLayer()->addDamage(source,_target->controller(),2); + } + tapped = newState; + } +}; + + +//1221 Serendib Efreet +class ASerendibEfreet:public MTGAbility{ + public: + ASerendibEfreet(int _id, MTGCardInstance * _source):MTGAbility(_id, _source){ + } + + void Update(float dt){ + if (newPhase == MTG_PHASE_UPKEEP && newPhase != currentPhase && game->currentPlayer == source->controller()){ + game->mLayers->stackLayer()->addDamage(source,game->currentPlayer,1); + } + } +}; + + +//1235 Aspect of Wolf +class AAspectOfWolf:public ListMaintainerAbility{ + public: + int color; + AAspectOfWolf(int _id, MTGCardInstance * _source, MTGCardInstance * _target):ListMaintainerAbility(_id, _source, _target){ + } + + int canBeInList(MTGCardInstance * card){ + + if (card->controller() == source->controller() && card->hasType("forest")) return 1; + return 0; + } + + int added(MTGCardInstance * card){ + MTGCardInstance * _target = (MTGCardInstance *) target; + int size = cards.size(); + if (size % 2 == 0){ + _target->power += 1; + }else{ + _target->addToToughness(1); + } + return 1; + } + + int removed(MTGCardInstance * card){ + MTGCardInstance * _target = (MTGCardInstance *) target; + int size = cards.size(); + if (size % 2 == 1){ + _target->power -= 1; + }else{ + _target->addToToughness(-1); + } + return 1; + } + +}; + +//1276 Wanderlust, 1148 Cursed Lands +class AWanderlust:public TriggeredAbility{ + public: + AWanderlust(int _id, MTGCardInstance * _source, MTGCardInstance * _target):TriggeredAbility(_id,_source, _target){} + + int trigger(){ + if (newPhase != currentPhase && newPhase == MTG_PHASE_UPKEEP && ((MTGCardInstance *) target)->controller()==game->currentPlayer){ + return 1; + } + return 0; + } + + int resolve(){ + game->mLayers->stackLayer()->addDamage(source,((MTGCardInstance *) target)->controller(),1); + return 1; + } +}; + +//1280 Atog +class AAtog:public TargetAbility{ + public: + Player * currentController; + int counters; + AAtog(int _id, MTGCardInstance * _source):TargetAbility(_id, _source,NULL, NULL, 0,0){ + currentController = source->controller(); + MTGGameZone * zones[] = {currentController->game->inPlay}; + tc = NEW TypeTargetChooser("artifact", zones, 1, source); + counters = 0; + } + + void Update(float dt){ + if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP){ + for (int i = 0; i < counters; i++){ + source->power-=2; + source->addToToughness(-2); + } + counters = 0; + } + TargetAbility::Update(dt); + Player * newController = source->controller(); + if (newController != currentController){ + delete tc; + MTGGameZone * zones[] = {newController->game->inPlay}; //In case Atog's controller changes + tc = NEW TypeTargetChooser("artifact", zones, 1, source); + currentController = newController; + } + } + + int resolve(){ + tc->getNextCardTarget()->controller()->game->putInGraveyard(tc->getNextCardTarget()); + source->power+=2; + source->addToToughness(2); + counters ++; + return 1; + } +}; + + + + +//1284 Dragon Whelp +class ADragonWhelp: public APowerToughnessModifierUntilEndOfTurn{ + public: + ADragonWhelp(int id, MTGCardInstance * card):APowerToughnessModifierUntilEndOfTurn(id, card, card, 1, 0, NEW ManaCost()){ + cost->add(MTG_COLOR_RED, 1); + } + + void Update(float dt){ + if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP && counters > 3){ + source->controller()->game->putInGraveyard(source); + } + APowerToughnessModifierUntilEndOfTurn::Update(dt); + } + +}; + +//1288 EarthBind +class AEarthbind:public ABasicAbilityModifier{ + public: + AEarthbind(int _id, MTGCardInstance * _source, MTGCardInstance * _target):ABasicAbilityModifier(_id,_source,_target,FLYING,0){ + if (value_before_modification) game->mLayers->stackLayer()->addDamage(source,target,2); + } +}; + +//1291 Fireball +class AFireball:public InstantAbility{ + public: + AFireball(int _id, MTGCardInstance * card, Spell * spell, int x):InstantAbility(_id, card){ + int nbtargets = spell->cursor; + int totaldamage = x+1-nbtargets; + int individualdamage = totaldamage / nbtargets; + Damageable * _target = spell->getNextDamageableTarget(); + while(_target){ + game->mLayers->stackLayer()->addDamage(source,_target,individualdamage); + _target = spell->getNextDamageableTarget(_target); + } + } +}; + +//1245 ForceOfNature +class AForceOfNature:public ActivatedAbility{ + public: + int dealDamageThisTurn; + AForceOfNature(int _id, MTGCardInstance * card):ActivatedAbility(_id,card, NEW ManaCost(),1,0){ + dealDamageThisTurn = 0; + cost->add(MTG_COLOR_GREEN,4); + } + + void Update(float dt){ + if (newPhase !=currentPhase){ + if (newPhase == MTG_PHASE_UNTAP){ + dealDamageThisTurn = 1; + }else if (newPhase == MTG_PHASE_DRAW && dealDamageThisTurn && game->currentPlayer==source->controller() ){ + game->mLayers->stackLayer()->addDamage(source,source->controller(),8); + } + } + ActivatedAbility::Update(dt); + } + + int isReactingToClick(MTGCardInstance * card){ + return (dealDamageThisTurn && currentPhase == MTG_PHASE_UPKEEP && ActivatedAbility::isReactingToClick(card)); + } + + int resolve(){ + dealDamageThisTurn = 0; + return 1; + } +}; + +//1301 KeldonWarlord +class AKeldonWarlord:public ListMaintainerAbility{ + public: + AKeldonWarlord(int _id, MTGCardInstance * _source):ListMaintainerAbility(_id, _source){ + } + + int canBeInList(MTGCardInstance * card){ + if (source->controller()->game->inPlay->hasCard(card) && card->isACreature() && !card->hasType("wall") ) return 1; + return 0; + } + + int added(MTGCardInstance * card){ + source->power += 1; + source->addToToughness(1); + return 1; + } + + int removed(MTGCardInstance * card){ + source->power -= 1; + source->addToToughness(-1); + return 1; + } + +}; + +//1302 : Kird Ape +class AKirdApe:public MTGAbility{ + public: + int init; + AKirdApe(int _id, MTGCardInstance * _source):MTGAbility(_id, _source){ + init = 0; + } + + void Update(float dt){ + if (source->controller()->game->inPlay->hasType("forest")){ + if(!init){ + init = 1; + source->power+=1; + source->addToToughness(2); + } + }else{ + if (init){ + init = 0; + source->power-=1; + source->addToToughness(-2); + } + } + } +}; + +//1309 Orcish Artilery +class AOrcishArtillery: public ADamager{ + public: + AOrcishArtillery(int _id,MTGCardInstance * card): ADamager(_id, card, NEW ManaCost(), 2){ + } + + int resolve(){ + ADamager::resolve(); + game->mLayers->stackLayer()->addDamage(source,source->controller(), 3); + return 1; + } + +}; + +//1310 Orcish Oriflame +class AOrcishOriflame:public ListMaintainerAbility{ + public: + int color; + AOrcishOriflame(int _id, MTGCardInstance * _source):ListMaintainerAbility(_id, _source){ + } + + int canBeInList(MTGCardInstance * card){ + if (source->controller() == game->currentPlayer && game->currentPlayer->game->inPlay->hasCard(card) && card->attacker) return 1; + return 0; + } + + int added(MTGCardInstance * card){ + card->power += 1; + return 1; + } + + int removed(MTGCardInstance * card){ + card->power -= 1; + return 1; + } + +}; + +//1334 Castle +class ACastle:public ListMaintainerAbility{ + public: + ACastle(int _id, MTGCardInstance * _source):ListMaintainerAbility(_id, _source){ + } + + int canBeInList(MTGCardInstance * card){ + if (source->controller()->game->inPlay->hasCard(card) && card->isACreature() && !card->isAttacker() && !card->tapped) return 1; + return 0; + } + + int added(MTGCardInstance * card){ + card->addToToughness(2); + return 1; + } + + int removed(MTGCardInstance * card){ + card->addToToughness(-2); + return 1; + } +}; + + +//1351 Island Sanctuary +class AIslandSanctuary:public MTGAbility{ + public: + int initThisTurn; + AIslandSanctuary(int _id, MTGCardInstance * _source):MTGAbility(_id, _source){ + initThisTurn = 0; + } + + void Update(float dt){ + if (currentPhase == MTG_PHASE_UNTAP && game->currentPlayer == source->controller()) initThisTurn = 0; + + if (initThisTurn && currentPhase == MTG_PHASE_COMBATATTACKERS && game->currentPlayer != source->controller()){ + MTGGameZone * zone = game->currentPlayer->game->inPlay; + for (int i = 0; i < zone->nb_cards; i++){ + MTGCardInstance * card = zone->cards[i]; + if (card->isAttacker() && !card->basicAbilities[FLYING] && !card->basicAbilities[ISLANDWALK]) card->attacker=0; + } + } + } + + int isReactingToClick(MTGCardInstance * card){ + if (card==source && game->currentPlayer == card->controller() && currentPhase == MTG_PHASE_DRAW){ + Interruptible * action = game->mLayers->stackLayer()->_(-1); + if (action->type == ACTION_DRAW) return 1; + } + return 0; + } + + + int reactToClick(MTGCardInstance * card){ + if (!isReactingToClick(card)) return 0; + game->mLayers->stackLayer()->Remove(game->mLayers->stackLayer()->_(-1)); + initThisTurn = 1; + return 1; + } +}; + +//1352 Karma +class AKarma: public TriggeredAbility{ + public: + AKarma(int _id, MTGCardInstance * _source):TriggeredAbility(_id, _source){ + } + + int trigger(){ + if (newPhase != currentPhase && newPhase == MTG_PHASE_UPKEEP) return 1; + return 0; + } + + int resolve(){ + int totaldamage = 0; + MTGGameZone * zone = game->currentPlayer->game->inPlay; + for (int i = 0; i < zone->nb_cards; i++){ + if (zone->cards[i]->hasType("swamp")) totaldamage++;; + } + if (totaldamage) game->mLayers->stackLayer()->addDamage(source,game->currentPlayer, totaldamage); + return 1; + } +}; + +//1355 Norther Paladin +class ANorthernPaladin:public TargetAbility{ + public: + ANorthernPaladin(int _id, MTGCardInstance * card):TargetAbility(_id, card){ + int _cost[] = {MTG_COLOR_WHITE, 2}; + cost = NEW ManaCost(_cost,1); + tc = NEW TargetChooser(); + } + + int resolve(){ + MTGCardInstance * card = tc->getNextCardTarget(); + if (card->hasColor(MTG_COLOR_BLACK)){ + card->controller()->game->putInGraveyard(card); + return 1; + } + return 0; + } + + +}; + +//Sedge Troll +class ASedgeTroll:public MTGAbility{ + public: + int init; + ASedgeTroll(int _id, MTGCardInstance * _source):MTGAbility(_id, _source){ + init = 0; + } + + void Update(float dt){ + if (source->controller()->game->inPlay->hasType("swamp")){ + if(!init){ + init = 1; + source->power+=1; + source->addToToughness(1); + } + }else{ + if (init){ + init = 0; + source->power-=1; + source->addToToughness(-1); + } + } + } +}; + +//Soul Net +class ASoulNet:public ActivatedAbility{ + public: + PutInGraveyard * latest; + PutInGraveyard * newDead; + ASoulNet(int _id, MTGCardInstance * card):ActivatedAbility(_id, card,0,0,0){ + int _cost[] = {MTG_COLOR_ARTIFACT, 1}; + cost = NEW ManaCost(_cost,1); + latest = ((PutInGraveyard *) GameObserver::GetInstance()->mLayers->stackLayer()->getPrevious(NULL,ACTION_PUTINGRAVEYARD,RESOLVED_OK)); + newDead = latest; + } + + int isReactingToClick(MTGCardInstance * card){ + newDead = ((PutInGraveyard *) GameObserver::GetInstance()->mLayers->stackLayer()->getPrevious(NULL,ACTION_PUTINGRAVEYARD,RESOLVED_OK)); + if (newDead && newDead != latest && newDead->card->isACreature()) + return ActivatedAbility::isReactingToClick(card); + return 0; + } + int resolve(){ + latest = newDead; + source->controller()->life++; + return 1; + } +}; + + +//Stasis +class AStasis:public ActivatedAbility{ + public: + int paidThisTurn; + AStasis(int _id, MTGCardInstance * card):ActivatedAbility(_id,card, NEW ManaCost(),1,0){ + paidThisTurn = 1; + cost->add(MTG_COLOR_BLUE,1); + } + + void Update(float dt){ + //Upkeep Cost + if (newPhase !=currentPhase){ + if (newPhase == MTG_PHASE_UPKEEP){ + paidThisTurn = 0; + }else if (!paidThisTurn && newPhase > MTG_PHASE_UPKEEP && game->currentPlayer==source->controller() ){ + game->currentPlayer->game->putInGraveyard(source); + paidThisTurn = 1; + } + } + //Stasis Effect + for (int i = 0; i < 2; i++){ + game->phaseRing->removePhase(MTG_PHASE_UNTAP,game->players[i]); + } + + //Parent Class Method Call + ActivatedAbility::Update(dt); + } + + int isReactingToClick(MTGCardInstance * card){ + return (!paidThisTurn && currentPhase == MTG_PHASE_UPKEEP && ActivatedAbility::isReactingToClick(card)); + } + + int resolve(){ + paidThisTurn = 1; + return 1; + } + + int destroy(){ + for (int i = 0; i < 2; i++){ + game->phaseRing->addPhaseBefore(MTG_PHASE_UNTAP,game->players[i],MTG_PHASE_UPKEEP,game->players[i]); + } + return 1; + } +}; + + + +//--------------Addon Abra------------------ +//ShieldOfTheAge +class AShieldOfTheAge: public TargetAbility{ + public: + AShieldOfTheAge(int _id, MTGCardInstance * card):TargetAbility(_id,card,NEW DamageTargetChooser(card,_id),NEW ManaCost(),0,0){ + cost->add(MTG_COLOR_ARTIFACT,2); + } + + int resolve(){ + Damage * damage = tc->getNextDamageTarget(); + if (!damage) return 0; + game->mLayers->stackLayer()->Fizzle(damage); + return 1; + } +}; + +// GiveLifeForTappedType +class AGiveLifeForTappedType:public MTGAbility{ + public: + char type[20]; + int nbtypestapped; + + int counttypesTapped(){ + int result = 0; + MTGInPlay * inplay = source->controller()->opponent()->game->inPlay; + for (int i = 0; i < inplay->nb_cards; i++){ + MTGCardInstance * card = inplay->cards[i]; + if (card->tapped && card->hasType(type)) result++; + } + return result; + } + + AGiveLifeForTappedType(int _id, MTGCardInstance * source, const char * _type):MTGAbility(_id, source){ + sprintf(type,"%s",_type);{ + nbtypestapped = counttypesTapped(); + } + } + + void Update(float dt){ + int newcount = counttypesTapped(); + for (int i=0; i < newcount - nbtypestapped; i++){ + source->controller()->life++; + } + nbtypestapped = newcount; + } +}; + +// People of the Woods +class APeopleOfTheWoods:public ListMaintainerAbility{ + public: + APeopleOfTheWoods(int _id, MTGCardInstance * _source):ListMaintainerAbility(_id, _source){ + } + + int canBeInList(MTGCardInstance * card){ + if (source->controller()->game->inPlay->hasCard(card) && card->hasType("forest") ) return 1; + return 0; + } + + int added(MTGCardInstance * card){ + source->addToToughness(1); + return 1; + } + + int removed(MTGCardInstance * card){ + source->addToToughness(-1); + return 1; + } + +}; + +//Abomination Kill blocking creature if white or green +class AAbomination :public MTGAbility{ + public: + MTGCardInstance * opponents[20]; + int nbOpponents; + AAbomination (int _id, MTGCardInstance * _source):MTGAbility(_id, _source){ + nbOpponents = 0; + } + + void Update(float dt){ + if (newPhase != currentPhase){ + if( newPhase == MTG_PHASE_COMBATDAMAGE){ + nbOpponents = 0; + MTGCardInstance * opponent = source->getNextOpponent(); + while ((opponent && opponent->hasColor(MTG_COLOR_GREEN)) || opponent->hasColor(MTG_COLOR_WHITE)){ + opponents[nbOpponents] = opponent; + nbOpponents ++; + opponent = source->getNextOpponent(opponent); + } + }else if (newPhase == MTG_PHASE_COMBATEND){ + for (int i = 0; i < nbOpponents ; i++){ + game->mLayers->stackLayer()->addPutInGraveyard(opponents[i]); + } + } + } + } + + int testDestroy(){ + if(!game->isInPlay(source) && currentPhase != MTG_PHASE_UNTAP){ + return 0; + }else{ + return MTGAbility::testDestroy(); + } + } +}; + + + +//Minion of Leshrac +class AMinionofLeshrac: public TargetAbility{ + public: + int paidThisTurn; + AMinionofLeshrac(int _id, MTGCardInstance * source):TargetAbility(_id, source, NEW CreatureTargetChooser(),0,1,0){ + paidThisTurn = 1; + } + + void Update(float dt){ + if (newPhase != currentPhase && source->controller() == game->currentPlayer){ + if (newPhase == MTG_PHASE_UNTAP){ + paidThisTurn = 0; + }else if( newPhase == MTG_PHASE_UPKEEP + 1 && !paidThisTurn){ + game->mLayers->stackLayer()->addDamage(source,source->controller(), 5); + source->tapped = 1; + } + } + TargetAbility::Update(dt); + } + + int isReactingToClick(MTGCardInstance * card){ + if (currentPhase != MTG_PHASE_UPKEEP || paidThisTurn) return 0; + return TargetAbility::isReactingToClick(card); + } + + int resolve(){ + MTGCardInstance * card = tc->getNextCardTarget(); + if (card && card != source && card->controller() == source->controller()){ + card->controller()->game->putInGraveyard(card); + paidThisTurn = 1; + return 1; + } + return 0; + } + +}; + +//2703 Lost Order of Jarkeld +class ALostOrderofJarkeld:public ListMaintainerAbility{ + public: + ALostOrderofJarkeld(int _id, MTGCardInstance * _source):ListMaintainerAbility(_id, _source){ + } + + int canBeInList(MTGCardInstance * card){ + if (card==source || (game->currentPlayer->game->inPlay->hasCard(card) && card->isACreature()) ) return 1; + return 0; + } + + int added(MTGCardInstance * card){ + source->power += 1; + source->addToToughness(1); + return 1; + } + + int removed(MTGCardInstance * card){ + source->power -= 1; + source->addToToughness(-1); + return 1; + } + +}; + +//CreaturePowerToughnessModifierForAllTypeControlled +class ACreaturePowerToughnessModifierForAllTypeControlled:public ListMaintainerAbility{ + public: + char type[20]; + ACreaturePowerToughnessModifierForAllTypeControlled(int _id, MTGCardInstance * _source, const char * _type):ListMaintainerAbility(_id, _source){ + } + + int canBeInList(MTGCardInstance * card){ + if (source->controller()->game->inPlay->hasCard(card) && card->hasType(type) ) return 1; + return 0; + } + + int added(MTGCardInstance * card){ + source->power += 1; + source->addToToughness(1); + return 1; + } + + int removed(MTGCardInstance * card){ + source->power -= 1; + source->addToToughness(-1); + return 1; + } + +}; + +//GenericKirdApe +class AGenericKirdApe:public MTGAbility{ + public: + int init; + char type [20]; + int power; + int toughness; + AGenericKirdApe(int _id, MTGCardInstance * _source, const char * _type, int _power, int _toughness):MTGAbility(_id, _source){ + init = 0; + } + + void Update(float dt){ + if (source->controller()->game->inPlay->hasType(type)){ + if(!init){ + init = 1; + source->power+=power; + source->addToToughness(toughness); + } + }else{ + if (init){ + init = 0; + source->power-=power; + source->addToToughness(-toughness); + } + } + } +}; + + +//Rampage ability Tentative 2 +class ARampageAbility:public MTGAbility{ + public: + int nbOpponents; + int PowerModifier; + int ToughnessModifier; + int modifier; + ARampageAbility(int _id, MTGCardInstance * _source,int _PowerModifier, int _ToughnessModifier):MTGAbility(_id, _source){ + modifier=0; + } + void Update(float dt){ + if (source->isAttacker()){ + MTGInPlay * inPlay = game->opponent()->game->inPlay; + for (int i = 0; i < inPlay->nb_cards; i ++){ + MTGCardInstance * current = inPlay->cards[i]; + if (current->isDefenser()){ + modifier++; + } + } + source->power+= (PowerModifier * modifier); + source->addToToughness(ToughnessModifier * modifier); + } + } +}; + + +//Rampage ability Tentative 1 - Did not work as expected +class A1RampageAbility:public MTGAbility{ + public: + MTGCardInstance * opponents[20]; + int nbOpponents; + int PowerModifier; + int ToughnessModifier; + A1RampageAbility(int _id, MTGCardInstance * _source,int _PowerModifier, int _ToughnessModifier):MTGAbility(_id, _source){ + nbOpponents = 0; + } + + void Update(float dt){ + if (source->isAttacker()){ + if (newPhase != currentPhase){ + if( newPhase == MTG_PHASE_COMBATDAMAGE){ + nbOpponents = 0; + MTGCardInstance * opponent = source->getNextOpponent(); + while (opponent){ + opponents[nbOpponents] = opponent; + nbOpponents ++; + source->power+= PowerModifier; + source->addToToughness(ToughnessModifier); + opponent = source->getNextOpponent(opponent); + } + } + } + } + } +}; +#endif diff --git a/projects/mtg/include/Blocker.h b/projects/mtg/include/Blocker.h index 666e2f7be..c6569844b 100644 --- a/projects/mtg/include/Blocker.h +++ b/projects/mtg/include/Blocker.h @@ -13,36 +13,36 @@ class GameObserver; class MTGAbility; class Blocker : public MTGAbility { -protected: - ManaCost * manaCost; - int currentPhase; - void init(ManaCost * _cost); -public: - virtual ManaCost * untapManaCost(){return manaCost;}; - virtual int unblock(){return 1;}; - Blocker(int id, MTGCardInstance * card, ManaCost * _cost); - Blocker(int id, MTGCardInstance * card); - Blocker(int id, MTGCardInstance * card, MTGCardInstance *_target, ManaCost * _cost); - ~Blocker(); - virtual void Update(float dt); - virtual int destroy(); + protected: + ManaCost * manaCost; + int currentPhase; + void init(ManaCost * _cost); + public: + virtual ManaCost * untapManaCost(){return manaCost;}; + virtual int unblock(){return 1;}; + Blocker(int id, MTGCardInstance * card, ManaCost * _cost); + Blocker(int id, MTGCardInstance * card); + Blocker(int id, MTGCardInstance * card, MTGCardInstance *_target, ManaCost * _cost); + ~Blocker(); + virtual void Update(float dt); + virtual int destroy(); }; class Blockers { -protected: - int cursor; - int blockers[MAX_BLOCKERS]; - GameObserver * game; -public: - Blockers(); - ~Blockers(); - int Add (Blocker * ability); - int Remove (Blocker * ability); - int init(); - Blocker * next(); - int rewind(); - int isEmpty(); + protected: + int cursor; + int blockers[MAX_BLOCKERS]; + GameObserver * game; + public: + Blockers(); + ~Blockers(); + int Add (Blocker * ability); + int Remove (Blocker * ability); + int init(); + Blocker * next(); + int rewind(); + int isEmpty(); }; diff --git a/projects/mtg/include/CardDescriptor.h b/projects/mtg/include/CardDescriptor.h index 25205c001..f7e561009 100644 --- a/projects/mtg/include/CardDescriptor.h +++ b/projects/mtg/include/CardDescriptor.h @@ -1,5 +1,5 @@ /* -A Filter/Mask system for Card Instances to find cards matching specific settings such as color, type, etc... + A Filter/Mask system for Card Instances to find cards matching specific settings such as color, type, etc... */ #ifndef _CARDDESCRIPTOR_H_ @@ -12,16 +12,16 @@ A Filter/Mask system for Card Instances to find cards matching specific settings #define CD_AND 2 class CardDescriptor: public MTGCardInstance{ -protected: - MTGCardInstance * match_or(MTGCardInstance * card); - MTGCardInstance * match_and(MTGCardInstance * card); -public: - int mode; - int init(); - CardDescriptor(); - MTGCardInstance * match(MTGCardInstance * card); - MTGCardInstance * match(MTGGameZone * zone); - MTGCardInstance * nextmatch(MTGGameZone * zone, MTGCardInstance * previous); + protected: + MTGCardInstance * match_or(MTGCardInstance * card); + MTGCardInstance * match_and(MTGCardInstance * card); + public: + int mode; + int init(); + CardDescriptor(); + MTGCardInstance * match(MTGCardInstance * card); + MTGCardInstance * match(MTGGameZone * zone); + MTGCardInstance * nextmatch(MTGGameZone * zone, MTGCardInstance * previous); }; -#endif \ No newline at end of file +#endif diff --git a/projects/mtg/include/CardDisplay.h b/projects/mtg/include/CardDisplay.h index 441b55071..7f83d2b17 100644 --- a/projects/mtg/include/CardDisplay.h +++ b/projects/mtg/include/CardDisplay.h @@ -1,32 +1,32 @@ -#ifndef _CARD_DISPLAY_H_ -#define _CARD_DISPLAY_H_ - -#include "../include/PlayGuiObjectController.h" - -class TargetChooser; -class MTGGameZone; -class MTGCardInstance; - -class CardDisplay:public PlayGuiObjectController{ -public: - int x, y , start_item, nb_displayed_items; - TargetChooser * tc; - JGuiListener * listener; - CardDisplay(); - CardDisplay(int id, GameObserver* _game, int _x, int _y, JGuiListener * _listener, TargetChooser * _tc = NULL, int _nb_displayed_items = 7 ); - void AddCard(MTGCardInstance * _card); - void rotateLeft(); - void rotateRight(); - void CheckUserInput(float dt); - void Render(); - void init(MTGGameZone * zone); -}; - - - -class DefaultTargetDisplay:CardDisplay{ - public: - DefaultTargetDisplay(int id, GameObserver* _game, int _x, int _y, JGuiListener * _listener, int _nb_displayed_items ); - ~DefaultTargetDisplay(); -}; -#endif \ No newline at end of file +#ifndef _CARD_DISPLAY_H_ +#define _CARD_DISPLAY_H_ + +#include "../include/PlayGuiObjectController.h" + +class TargetChooser; +class MTGGameZone; +class MTGCardInstance; + +class CardDisplay:public PlayGuiObjectController{ + public: + int x, y , start_item, nb_displayed_items; + TargetChooser * tc; + JGuiListener * listener; + CardDisplay(); + CardDisplay(int id, GameObserver* _game, int _x, int _y, JGuiListener * _listener, TargetChooser * _tc = NULL, int _nb_displayed_items = 7 ); + void AddCard(MTGCardInstance * _card); + void rotateLeft(); + void rotateRight(); + void CheckUserInput(float dt); + void Render(); + void init(MTGGameZone * zone); +}; + + + +class DefaultTargetDisplay:CardDisplay{ + public: + DefaultTargetDisplay(int id, GameObserver* _game, int _x, int _y, JGuiListener * _listener, int _nb_displayed_items ); + ~DefaultTargetDisplay(); +}; +#endif diff --git a/projects/mtg/include/CardGui.h b/projects/mtg/include/CardGui.h index 37207d1d1..dbfe64924 100644 --- a/projects/mtg/include/CardGui.h +++ b/projects/mtg/include/CardGui.h @@ -12,18 +12,18 @@ class MTGCardInstance; class PlayGuiObject; class CardGui: public PlayGuiObject{ -protected: - hgeParticleSystem * mParticleSys; - int alpha; + protected: + hgeParticleSystem * mParticleSys; + int alpha; public: MTGCardInstance * card; CardGui(int id, MTGCardInstance * _card, float desiredHeight, float _x=0, float _y=0, bool hasFocus = false); virtual void Render(); - virtual void Update(float dt); + virtual void Update(float dt); - void RenderBig(float x=-1, float y = -1); - static void alternateRender(MTGCard * card, JLBFont * mFont, JQuad ** manaIcons, float x, float y, float rotation= 0, float scale=1); - ~CardGui(); + void RenderBig(float x=-1, float y = -1); + 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/ConstraintResolver.h b/projects/mtg/include/ConstraintResolver.h index ac4a80733..7cf28ecc2 100644 --- a/projects/mtg/include/ConstraintResolver.h +++ b/projects/mtg/include/ConstraintResolver.h @@ -6,9 +6,9 @@ class ConstraintResolver { -protected: -public: - static int untap(GameObserver * game, MTGCardInstance * card); + protected: + public: + static int untap(GameObserver * game, MTGCardInstance * card); }; #endif diff --git a/projects/mtg/include/Counters.h b/projects/mtg/include/Counters.h index 051b086a1..f9191638d 100644 --- a/projects/mtg/include/Counters.h +++ b/projects/mtg/include/Counters.h @@ -1,43 +1,43 @@ -#ifndef _COUNTERS_H_ -#define _COUNTERS_H_ -#include - - -using std::string; -class MTGCardInstance; - -/* One family of counters. Ex : +1/+1 */ -class Counter{ -public : - string name; - int nb; - int power, toughness; - MTGCardInstance * target; - Counter(MTGCardInstance * _target, int _power, int _toughness); - Counter(MTGCardInstance * _target, const char * _name,int _power = 0 , int _toughness = 0 ); - int init(MTGCardInstance * _target,const char * _name, int _power, int _toughness); - bool sameAs(const char * _name, int _power, int _toughness); - bool cancels(int _power, int _toughness); - int added(); - int removed(); -}; - -/* Various families of counters attached to an instance of a card */ -class Counters{ -public: - int mCount; - Counter * counters[10]; - MTGCardInstance * target; - Counters(MTGCardInstance * _target); - ~Counters(); - int addCounter(const char * _name,int _power = 0, int _toughness = 0); - int addCounter(int _power, int _toughness); - int removeCounter(const char * _name,int _power = 0, int _toughness = 0); - int removeCounter(int _power, int _toughness); - Counter * hasCounter(const char * _name,int _power = 0, int _toughness = 0); - Counter * hasCounter(int _power, int _toughness); - Counter * getNext(Counter * previous = NULL); -}; - - -#endif \ No newline at end of file +#ifndef _COUNTERS_H_ +#define _COUNTERS_H_ +#include + + +using std::string; +class MTGCardInstance; + +/* One family of counters. Ex : +1/+1 */ +class Counter{ + public : + string name; + int nb; + int power, toughness; + MTGCardInstance * target; + Counter(MTGCardInstance * _target, int _power, int _toughness); + Counter(MTGCardInstance * _target, const char * _name,int _power = 0 , int _toughness = 0 ); + int init(MTGCardInstance * _target,const char * _name, int _power, int _toughness); + bool sameAs(const char * _name, int _power, int _toughness); + bool cancels(int _power, int _toughness); + int added(); + int removed(); +}; + +/* Various families of counters attached to an instance of a card */ +class Counters{ + public: + int mCount; + Counter * counters[10]; + MTGCardInstance * target; + Counters(MTGCardInstance * _target); + ~Counters(); + int addCounter(const char * _name,int _power = 0, int _toughness = 0); + int addCounter(int _power, int _toughness); + int removeCounter(const char * _name,int _power = 0, int _toughness = 0); + int removeCounter(int _power, int _toughness); + Counter * hasCounter(const char * _name,int _power = 0, int _toughness = 0); + Counter * hasCounter(int _power, int _toughness); + Counter * getNext(Counter * previous = NULL); +}; + + +#endif diff --git a/projects/mtg/include/Damage.h b/projects/mtg/include/Damage.h index 252769590..ade90a3cb 100644 --- a/projects/mtg/include/Damage.h +++ b/projects/mtg/include/Damage.h @@ -14,43 +14,43 @@ class GameObserver; #define DAMAGEABLE_PLAYER 1 class Damageable { -protected: + protected: -public: - int life; - int type_as_damageable; - Damageable(int _life){life=_life;}; - int getLife(){return life;}; - virtual int dealDamage(int damage){life-=damage;return life;}; - virtual int afterDamage(){return 0;} - virtual JQuad * getIcon(){return NULL;}; + public: + int life; + int type_as_damageable; + Damageable(int _life){life=_life;}; + int getLife(){return life;}; + virtual int dealDamage(int damage){life-=damage;return life;}; + virtual int afterDamage(){return 0;} + virtual JQuad * getIcon(){return NULL;}; }; class Damage: public Interruptible { -protected: - void init(MTGCardInstance * _source, Damageable * _target, int _damage); -public: - Damageable * target; - MTGCardInstance * source; - int damage; - void Render(); - Damage(int id, MTGCardInstance* _source, Damageable * _target); - Damage(int id, MTGCardInstance* _source, Damageable * _target, int _damage); - int resolve(); + protected: + void init(MTGCardInstance * _source, Damageable * _target, int _damage); + public: + Damageable * target; + MTGCardInstance * source; + int damage; + void Render(); + Damage(int id, MTGCardInstance* _source, Damageable * _target); + Damage(int id, MTGCardInstance* _source, Damageable * _target, int _damage); + int resolve(); }; class DamageStack :public GuiLayer, public Interruptible{ -protected: - int currentState; + protected: + int currentState; -public: - int resolve(); - void Render(); - int CombatDamages();//Deprecated ? - int CombatDamages(int strike); - DamageStack(int id, GameObserver* _game); + public: + int resolve(); + void Render(); + int CombatDamages();//Deprecated ? + int CombatDamages(int strike); + DamageStack(int id, GameObserver* _game); }; diff --git a/projects/mtg/include/DamageResolverLayer.h b/projects/mtg/include/DamageResolverLayer.h index a6ff1228b..0668f712e 100644 --- a/projects/mtg/include/DamageResolverLayer.h +++ b/projects/mtg/include/DamageResolverLayer.h @@ -1,38 +1,38 @@ -#ifndef _DAMAGERESOLVERLAYER_H_ -#define _DAMAGERESOLVERLAYER_H_ -#include "../include/PlayGuiObjectController.h" - -class MTGCardInstance; -class DamagerDamaged; -class DamageStack; - - -class DamageResolverLayer:public PlayGuiObjectController{ -protected: - int trampleDamage(); -public: - int buttonOk; - int currentPhase; - int remainingDamageSteps; - Player * currentChoosingPlayer; - DamageStack * damageStack; - DamagerDamaged * currentSource; - - DamageResolverLayer(int id, GameObserver* _game); - int init(); - int initResolve(); - Player * whoSelectsDamagesDealtBy(MTGCardInstance * card); - int addAutoDamageToOpponents(MTGCardInstance * card); - int addIfNotExists(MTGCardInstance * card, Player * selecter); - int addDamager(MTGCardInstance * card, Player * selecter); - DamagerDamaged * findByCard(MTGCardInstance * card); -int canStopDealDamages(); -int resolveDamages(); -int isOpponent(DamagerDamaged * a, DamagerDamaged * b); - void nextPlayer(); - virtual void Update(float dt); - virtual void CheckUserInput(float dt); - virtual void Render(); -}; - -#endif +#ifndef _DAMAGERESOLVERLAYER_H_ +#define _DAMAGERESOLVERLAYER_H_ +#include "../include/PlayGuiObjectController.h" + +class MTGCardInstance; +class DamagerDamaged; +class DamageStack; + + +class DamageResolverLayer:public PlayGuiObjectController{ + protected: + int trampleDamage(); + public: + int buttonOk; + int currentPhase; + int remainingDamageSteps; + Player * currentChoosingPlayer; + DamageStack * damageStack; + DamagerDamaged * currentSource; + + DamageResolverLayer(int id, GameObserver* _game); + int init(); + int initResolve(); + Player * whoSelectsDamagesDealtBy(MTGCardInstance * card); + int addAutoDamageToOpponents(MTGCardInstance * card); + int addIfNotExists(MTGCardInstance * card, Player * selecter); + int addDamager(MTGCardInstance * card, Player * selecter); + DamagerDamaged * findByCard(MTGCardInstance * card); + int canStopDealDamages(); + int resolveDamages(); + int isOpponent(DamagerDamaged * a, DamagerDamaged * b); + void nextPlayer(); + virtual void Update(float dt); + virtual void CheckUserInput(float dt); + virtual void Render(); +}; + +#endif diff --git a/projects/mtg/include/DamagerDamaged.h b/projects/mtg/include/DamagerDamaged.h index cff1f44d3..87fafcc97 100644 --- a/projects/mtg/include/DamagerDamaged.h +++ b/projects/mtg/include/DamagerDamaged.h @@ -1,30 +1,30 @@ -#ifndef _DAMAGERDAMAGED_H_ -#define _DAMAGERDAMAGED_H_ - -#include "../include/CardGui.h" - -class Player; - -class DamagerDamaged:public CardGui{ -public: - Player * damageSelecter; - int mCount; - Damage * damages[10]; - int damageToDeal; - - int dealOneDamage(DamagerDamaged * target); - int addDamage(int damage, DamagerDamaged * source); - int removeDamagesTo(DamagerDamaged * target); - int removeDamagesFrom(DamagerDamaged * source); - int sumDamages(); - int hasLethalDamage(); - DamagerDamaged(CardGui * cardg, Player * _damageSelecter, bool _hasFocus); - ~DamagerDamaged(); - void Render(Player * currentPlayer); - - - -}; - - -#endif \ No newline at end of file +#ifndef _DAMAGERDAMAGED_H_ +#define _DAMAGERDAMAGED_H_ + +#include "../include/CardGui.h" + +class Player; + +class DamagerDamaged:public CardGui{ + public: + Player * damageSelecter; + int mCount; + Damage * damages[10]; + int damageToDeal; + + int dealOneDamage(DamagerDamaged * target); + int addDamage(int damage, DamagerDamaged * source); + int removeDamagesTo(DamagerDamaged * target); + int removeDamagesFrom(DamagerDamaged * source); + int sumDamages(); + int hasLethalDamage(); + DamagerDamaged(CardGui * cardg, Player * _damageSelecter, bool _hasFocus); + ~DamagerDamaged(); + void Render(Player * currentPlayer); + + + +}; + + +#endif diff --git a/projects/mtg/include/DeckDataWrapper.h b/projects/mtg/include/DeckDataWrapper.h index 56ed5c408..2d24d7091 100644 --- a/projects/mtg/include/DeckDataWrapper.h +++ b/projects/mtg/include/DeckDataWrapper.h @@ -1,48 +1,48 @@ -#ifndef _DECKDATAWRAPPER_H_ -#define _DECKDATAWRAPPER_H_ - -#include "../include/MTGDefinitions.h" -#include "../include/MTGCard.h" +#ifndef _DECKDATAWRAPPER_H_ +#define _DECKDATAWRAPPER_H_ + +#include "../include/MTGDefinitions.h" +#include "../include/MTGCard.h" #include #include -using std::map; -using std::string; - -class MTGDeck; - - -class Cmp1 { // compares cards by their name - public: - bool operator()(MTGCard * card1, MTGCard * card2) const { - if (!card2) return true; - if (!card1) return false; - string name1 = card1->name; - string name2 = card2->name; - int result = name1.compare(name2); - if (!result) return card1->getMTGId() < card2->getMTGId(); - return ( result < 0); - } -}; - -class DeckDataWrapper{ -public: - int colors[MTG_NB_COLORS+1]; - int currentColor; - map cards; - int currentposition; - MTGDeck * parent; - - DeckDataWrapper(MTGDeck * deck); - ~DeckDataWrapper(); - - int Add(MTGCard * card); - int Remove(MTGCard * card); - MTGCard * getNext(MTGCard * previous = NULL, int color = -1); - MTGCard * getPrevious(MTGCard * next = NULL, int color = -1); - void updateCounts(MTGCard * card = NULL, int removed = 0); - void updateCurrentPosition(MTGCard * currentCard,int color = -1); - int getCount(int color = -1); - void save(); -}; - -#endif \ No newline at end of file +using std::map; +using std::string; + +class MTGDeck; + + +class Cmp1 { // compares cards by their name + public: + bool operator()(MTGCard * card1, MTGCard * card2) const { + if (!card2) return true; + if (!card1) return false; + string name1 = card1->name; + string name2 = card2->name; + int result = name1.compare(name2); + if (!result) return card1->getMTGId() < card2->getMTGId(); + return ( result < 0); + } +}; + +class DeckDataWrapper{ + public: + int colors[MTG_NB_COLORS+1]; + int currentColor; + map cards; + int currentposition; + MTGDeck * parent; + + DeckDataWrapper(MTGDeck * deck); + ~DeckDataWrapper(); + + int Add(MTGCard * card); + int Remove(MTGCard * card); + MTGCard * getNext(MTGCard * previous = NULL, int color = -1); + MTGCard * getPrevious(MTGCard * next = NULL, int color = -1); + void updateCounts(MTGCard * card = NULL, int removed = 0); + void updateCurrentPosition(MTGCard * currentCard,int color = -1); + int getCount(int color = -1); + void save(); +}; + +#endif diff --git a/projects/mtg/include/DuelLayers.h b/projects/mtg/include/DuelLayers.h index a33b634d4..631c5fc78 100644 --- a/projects/mtg/include/DuelLayers.h +++ b/projects/mtg/include/DuelLayers.h @@ -1,34 +1,34 @@ -#ifndef _DUELLAYERS_H_ -#define _DUELLAYERS_H_ - - -#include "GuiLayers.h" - -class MTGGuiHand; -class MTGGuiPlay; -class ActionLayer; -class ActionStack; -class DamageResolverLayer; - -class DuelLayers: public GuiLayers{ - -public: - ActionLayer * actionLayer(); - MTGGuiHand * handLayer(); - MTGGuiPlay * playLayer(); - ActionStack * stackLayer(); - DamageResolverLayer * combatLayer(); - void init(); - -}; - -#include "ActionLayer.h" -#include "GameObserver.h" -#include "MTGGamePhase.h" -#include "MTGGuiHand.h" -#include "MTGGuiPlay.h" -#include "ActionStack.h" -#include "Damage.h" - - -#endif +#ifndef _DUELLAYERS_H_ +#define _DUELLAYERS_H_ + + +#include "GuiLayers.h" + +class MTGGuiHand; +class MTGGuiPlay; +class ActionLayer; +class ActionStack; +class DamageResolverLayer; + +class DuelLayers: public GuiLayers{ + + public: + ActionLayer * actionLayer(); + MTGGuiHand * handLayer(); + MTGGuiPlay * playLayer(); + ActionStack * stackLayer(); + DamageResolverLayer * combatLayer(); + void init(); + +}; + +#include "ActionLayer.h" +#include "GameObserver.h" +#include "MTGGamePhase.h" +#include "MTGGuiHand.h" +#include "MTGGuiPlay.h" +#include "ActionStack.h" +#include "Damage.h" + + +#endif diff --git a/projects/mtg/include/GameApp.h b/projects/mtg/include/GameApp.h index 402d16b11..6076d7aeb 100644 --- a/projects/mtg/include/GameApp.h +++ b/projects/mtg/include/GameApp.h @@ -1,88 +1,88 @@ -/* -* Wagic, The Homebrew ?! is licensed under the BSD license -* See LICENSE in the Folder's root -* http://wololo.net/wagic/ -*/ - - - - - -#ifndef _GAMEAPP_H_ -#define _GAMEAPP_H_ - - -#include "../include/Logger.h" - - -#include -#include -#include -#include -#include - - -#include - - -#include "../include/GameState.h" - -#include "../include/MTGDeck.h" -#include "../include/MTGCard.h" -#include "../include/MTGGameZones.h" - -#include "../include/TexturesCache.h" - -#define MAX_STATE 6 - - -#define PLAYER_TYPE_CPU 0 -#define PLAYER_TYPE_HUMAN 1 -#define PLAYER_TYPE_TESTSUITE 2 - - -class MTGAllCards; -class TexturesCache; - - - - - -class GameApp: public JApp -{ - -private: - bool mShowDebugInfo; - int mScreenShotCount; - - GameState* mCurrentState; - GameState* mNextState; - GameState* mGameStates[MAX_STATE]; - - -public: - int players[2]; - MTGAllCards * collection; - TexturesCache * cache; - - GameApp(); - virtual ~GameApp(); - - virtual void Create(); - virtual void Destroy(); - virtual void Update(); - virtual void Render(); - virtual void Pause(); - virtual void Resume(); - - void LoadGameStates(); - void SetNextState(int state); - static JResourceManager * CommonRes; - static hgeParticleSystem * Particles[6]; - static int HasMusic; - -}; - - - -#endif +/* + * Wagic, The Homebrew ?! is licensed under the BSD license + * See LICENSE in the Folder's root + * http://wololo.net/wagic/ + */ + + + + + +#ifndef _GAMEAPP_H_ +#define _GAMEAPP_H_ + + +#include "../include/Logger.h" + + +#include +#include +#include +#include +#include + + +#include + + +#include "../include/GameState.h" + +#include "../include/MTGDeck.h" +#include "../include/MTGCard.h" +#include "../include/MTGGameZones.h" + +#include "../include/TexturesCache.h" + +#define MAX_STATE 6 + + +#define PLAYER_TYPE_CPU 0 +#define PLAYER_TYPE_HUMAN 1 +#define PLAYER_TYPE_TESTSUITE 2 + + +class MTGAllCards; +class TexturesCache; + + + + + +class GameApp: public JApp +{ + + private: + bool mShowDebugInfo; + int mScreenShotCount; + + GameState* mCurrentState; + GameState* mNextState; + GameState* mGameStates[MAX_STATE]; + + + public: + int players[2]; + MTGAllCards * collection; + TexturesCache * cache; + + GameApp(); + virtual ~GameApp(); + + virtual void Create(); + virtual void Destroy(); + virtual void Update(); + virtual void Render(); + virtual void Pause(); + virtual void Resume(); + + void LoadGameStates(); + void SetNextState(int state); + static JResourceManager * CommonRes; + static hgeParticleSystem * Particles[6]; + static int HasMusic; + +}; + + + +#endif diff --git a/projects/mtg/include/GameObserver.h b/projects/mtg/include/GameObserver.h index 759bb88ba..0875a5c5b 100644 --- a/projects/mtg/include/GameObserver.h +++ b/projects/mtg/include/GameObserver.h @@ -23,49 +23,49 @@ class TargetChooser; class GameObserver{ protected: - int reaction; - static GameObserver * mInstance; - MTGCardInstance * cardWaitingForTargets; + int reaction; + static GameObserver * mInstance; + MTGCardInstance * cardWaitingForTargets; int nbPlayers; int currentPlayerId; int currentRound; - - int targetListIsSet(MTGCardInstance * card); + + int targetListIsSet(MTGCardInstance * card); public: PhaseRing * phaseRing; int cancelCurrentAction(); int currentGamePhase; - int oldGamePhase; - TargetChooser * targetChooser; - DuelLayers * mLayers; - Player * gameOver; - Player * players[2]; //created outside + int oldGamePhase; + TargetChooser * targetChooser; + DuelLayers * mLayers; + Player * gameOver; + Player * players[2]; //created outside MTGGamePhase * gamePhaseManager; //Created Outside ? - TargetChooser * getCurrentTargetChooser(); - void stackObjectClicked(Interruptible * action); + TargetChooser * getCurrentTargetChooser(); + void stackObjectClicked(Interruptible * action); - void cardClick(MTGCardInstance * card,Targetable * _object = NULL ); - int enteringPhase(int phase); - int getCurrentGamePhase(); - void userRequestNextGamePhase(); - void nextGamePhase(); - void cleanupPhase(); - void nextPlayer(); - static void Init(Player * _players[], int _nbplayers); - static GameObserver * GetInstance(); - static void EndInstance(); + void cardClick(MTGCardInstance * card,Targetable * _object = NULL ); + int enteringPhase(int phase); + int getCurrentGamePhase(); + void userRequestNextGamePhase(); + void nextGamePhase(); + void cleanupPhase(); + void nextPlayer(); + static void Init(Player * _players[], int _nbplayers); + static GameObserver * GetInstance(); + static void EndInstance(); Player * currentPlayer; - Player * currentActionPlayer; - Player * isInterrupting; - Player * opponent(); - Player * currentlyActing(); + Player * currentActionPlayer; + Player * isInterrupting; + Player * opponent(); + Player * currentlyActing(); GameObserver(Player * _players[], int _nbplayers); - ~GameObserver(); + ~GameObserver(); void setGamePhaseManager(MTGGamePhase * _phases); - void stateEffects(); + void stateEffects(); void eventOccured(); void addObserver(MTGAbility * observer); void removeObserver(ActionElement * observer); @@ -73,7 +73,7 @@ class GameObserver{ void nextStep(); void untapPhase(); void draw(); - int canPutInPlay(MTGCardInstance * card); + int canPutInPlay(MTGCardInstance * card); void putInPlay(MTGCardInstance * card); int isInPlay(MTGCardInstance * card); int isACreature(MTGCardInstance * card); diff --git a/projects/mtg/include/GameOptions.h b/projects/mtg/include/GameOptions.h index da75d92ec..bffad59db 100644 --- a/projects/mtg/include/GameOptions.h +++ b/projects/mtg/include/GameOptions.h @@ -1,24 +1,24 @@ -#ifndef _GAME_OPTIONS_H_ -#define _GAME_OPTIONS_H_ - - -#define MAX_OPTIONS 50 -#define OPTIONS_MUSICVOLUME 0 -#define OPTIONS_INTERRUPTATENDOFPHASE_OFFSET 1 -#define OPTIONS_SAVEFILE "Res/settings/options.txt" -class GameOptions { -public: - int values[MAX_OPTIONS]; - static GameOptions * GetInstance(); - static void Destroy(); - int save(); - int load(); - -private: - GameOptions(); - ~GameOptions(); - static GameOptions* mInstance; - -}; - -#endif \ No newline at end of file +#ifndef _GAME_OPTIONS_H_ +#define _GAME_OPTIONS_H_ + + +#define MAX_OPTIONS 50 +#define OPTIONS_MUSICVOLUME 0 +#define OPTIONS_INTERRUPTATENDOFPHASE_OFFSET 1 +#define OPTIONS_SAVEFILE "Res/settings/options.txt" +class GameOptions { + public: + int values[MAX_OPTIONS]; + static GameOptions * GetInstance(); + static void Destroy(); + int save(); + int load(); + + private: + GameOptions(); + ~GameOptions(); + static GameOptions* mInstance; + +}; + +#endif diff --git a/projects/mtg/include/GameState.h b/projects/mtg/include/GameState.h index 27f60b214..b66e52e90 100644 --- a/projects/mtg/include/GameState.h +++ b/projects/mtg/include/GameState.h @@ -1,46 +1,46 @@ -#ifndef _GAME_STATE_H_ -#define _GAME_STATE_H_ - -#define FADING_SPEED 350.0f - -class JGE; - -#include - -enum _gameSates -{ - GAME_STATE_MENU, - GAME_STATE_DUEL, - GAME_STATE_DECK_VIEWER, - GAME_STATE_SHOP, - GAME_STATE_OPTIONS -}; - - -class GameApp; - -class GameState -{ -protected: - GameApp* mParent; - JGE* mEngine; - -public: - - static const char * const menuTexts[]; - GameState(GameApp* parent); - virtual ~GameState() {} - - virtual void Create() {} - virtual void Destroy() {} - - virtual void Start() {} - virtual void End() {} - - virtual void Update(float dt) = 0; - virtual void Render() = 0; -}; - - -#endif - +#ifndef _GAME_STATE_H_ +#define _GAME_STATE_H_ + +#define FADING_SPEED 350.0f + +class JGE; + +#include + +enum _gameSates + { + GAME_STATE_MENU, + GAME_STATE_DUEL, + GAME_STATE_DECK_VIEWER, + GAME_STATE_SHOP, + GAME_STATE_OPTIONS + }; + + +class GameApp; + +class GameState +{ + protected: + GameApp* mParent; + JGE* mEngine; + + public: + + static const char * const menuTexts[]; + GameState(GameApp* parent); + virtual ~GameState() {} + + virtual void Create() {} + virtual void Destroy() {} + + virtual void Start() {} + virtual void End() {} + + virtual void Update(float dt) = 0; + virtual void Render() = 0; +}; + + +#endif + diff --git a/projects/mtg/include/GameStateDeckViewer.h b/projects/mtg/include/GameStateDeckViewer.h index 42392cea7..25dd85155 100644 --- a/projects/mtg/include/GameStateDeckViewer.h +++ b/projects/mtg/include/GameStateDeckViewer.h @@ -1,790 +1,790 @@ -#ifndef _GAME_STATE_DECK_VIEWER_H_ -#define _GAME_STATE_DECK_VIEWER_H_ - -#include -#include - -#include - -#include "GameState.h" -#include "SimpleMenu.h" -#include "../include/CardGui.h" -#include "../include/GameOptions.h" -#include "../include/PriceList.h" -#include "../include/PlayerData.h" -#include "../include/DeckDataWrapper.h" - -#define NO_USER_ACTIVITY_HELP_DELAY 10 -#define NO_USER_ACTIVITY_SHOWCARD_DELAY 0.1 - -#define STAGE_WAITING 2 -#define STAGE_TRANSITION_LEFT 1 -#define STAGE_TRANSITION_RIGHT 0 -#define STAGE_TRANSITION_UP 3 -#define STAGE_TRANSITION_DOWN 4 -#define STAGE_ONSCREEN_MENU 5 -#define STAGE_WELCOME 6 -#define STAGE_MENU 7 - - -#define ALL_COLORS -1 - -#define ROTATE_LEFT 1; -#define ROTATE_RIGHT 0; - - - - -class GameStateDeckViewer: public GameState, public JGuiListener -{ -private: - JQuad * mIcons[7]; - JQuad * pspIcons[8]; - JTexture * pspIconsTexture; - float last_user_activity; - float onScreenTransition; - float mRotation; - float mSlide; - int mAlpha; - int mStage; - - int colorFilter; - JMusic * bgMusic; - JTexture * backTex; - JQuad * backQuad; - SimpleMenu * welcome_menu; - JLBFont * mFont; - bool showing_user_deck; - JLBFont * menuFont; - SimpleMenu * menu; - SimpleMenu * sellMenu; - PriceList* pricelist; - PlayerData * playerdata; - int price; - DeckDataWrapper * displayed_deck; - DeckDataWrapper * myDeck; - DeckDataWrapper * myCollection; - MTGCard * currentCard; - MTGCard * cardIndex[7]; - int hudAlpha; -public: - - GameStateDeckViewer(GameApp* parent): GameState(parent) { - bgMusic = NULL; - } - virtual ~GameStateDeckViewer() { - SAFE_DELETE(bgMusic); - } - - - void rotateCards(int direction){ - int maxCards=displayed_deck->getCount(colorFilter); - if (maxCards==0) - return; - int left = direction; - if (left){ - MTGCard * currentCard = displayed_deck->getNext(cardIndex[6],colorFilter); - for (int i = 1; i<7; i++){ - cardIndex[i-1] = cardIndex[i]; - } - cardIndex[6] = currentCard; - }else{ - MTGCard * currentCard = displayed_deck->getPrevious(cardIndex[0],colorFilter); - for (int i = 5; i>=0; i--){ - cardIndex[i+1] = cardIndex[i]; - } - cardIndex[0] = currentCard; - } - displayed_deck->updateCurrentPosition(cardIndex[2],colorFilter); - } - - void loadIndexes(MTGCard * current = NULL){ - for (int i = 0; i < 7; i++){ - cardIndex[i] = NULL; - } - MTGCard * _current = current; - _current = displayed_deck->getNext(NULL,colorFilter); - for (int i = 0; i < 7; i++){ - cardIndex[i] = _current; -#if defined (WIN32) || defined (LINUX) - char buf[4096]; - sprintf(buf,"Loadindexes[%i] is NULL\n", i); - if(_current) sprintf(buf, "LoadIndexes[%i] : %s\n", i, _current->getName()); - OutputDebugString(buf); -#endif - _current = displayed_deck->getNext(_current,colorFilter); - - } - displayed_deck->updateCurrentPosition(cardIndex[2],colorFilter); - } - - void switchDisplay(){ -#if defined (WIN32) || defined (LINUX) - OutputDebugString("Switching display"); -#endif - if (displayed_deck == myCollection){ - displayed_deck = myDeck; - }else{ - displayed_deck = myCollection; - } - currentCard = NULL; - loadIndexes(); - } - - virtual void Start() - { - hudAlpha = 0; - pricelist = NEW PriceList("Res/settings/prices.dat",mParent->collection); - playerdata = NEW PlayerData(mParent->collection); - sellMenu = NULL; - myCollection = NEW DeckDataWrapper(NEW MTGDeck("Res/player/collection.dat", mParent->cache,mParent->collection)); - displayed_deck = myCollection; - myDeck = NULL; - menuFont = GameApp::CommonRes->GetJLBFont("graphics/f3"); - mFont = GameApp::CommonRes->GetJLBFont("graphics/magic"); - - - - - menu = NEW SimpleMenu(11,this,menuFont,SCREEN_WIDTH/2-100,20,200); - menu->Add(11,"Save"); - menu->Add(12,"Back to main menu"); - menu->Add(13, "Cancel"); - - - //icon images - mIcons[MTG_COLOR_ARTIFACT] = GameApp::CommonRes->GetQuad("c_artifact"); - mIcons[MTG_COLOR_LAND] = GameApp::CommonRes->GetQuad("c_land"); - mIcons[MTG_COLOR_WHITE] = GameApp::CommonRes->GetQuad("c_white"); - mIcons[MTG_COLOR_RED] = GameApp::CommonRes->GetQuad("c_red"); - mIcons[MTG_COLOR_BLACK] = GameApp::CommonRes->GetQuad("c_black"); - mIcons[MTG_COLOR_BLUE] = GameApp::CommonRes->GetQuad("c_blue"); - mIcons[MTG_COLOR_GREEN] = GameApp::CommonRes->GetQuad("c_green"); - for (int i=0; i < 7; i++){ - mIcons[i]->SetHotSpot(16,16); - } - - - pspIconsTexture = JRenderer::GetInstance()->LoadTexture("graphics/iconspsp.png", TEX_TYPE_USE_VRAM); - - for (int i=0; i < 8; i++){ - pspIcons[i] = NEW JQuad(pspIconsTexture, i*32, 0, 32, 32); - pspIcons[i]->SetHotSpot(16,16); - } - - - backTex = JRenderer::GetInstance()->LoadTexture("sets/back.jpg", TEX_TYPE_USE_VRAM); - backQuad = NEW JQuad(backTex, 0, 0, 200, 285); // Create quad for rendering. - -//menuFont = NEW JLBFont("graphics/f3",16); -menuFont = GameApp::CommonRes->GetJLBFont("graphics/f3"); - welcome_menu = NEW SimpleMenu(10,this,menuFont,20,20,200); - char buffer[100]; - for (int i=1; i < 6; i++){ - sprintf(buffer, "Res/player/deck%i.txt",i); - std::ifstream file(buffer); - if(file){ - welcome_menu->Add(i, GameState::menuTexts[i]); - file.close(); - }else{ - welcome_menu->Add(i, GameState::menuTexts[0]); - } - - } - welcome_menu->Add(10, "Cancel"); - - if (GameApp::HasMusic && GameOptions::GetInstance()->values[OPTIONS_MUSICVOLUME] > 0){ - if (!bgMusic) bgMusic = JSoundSystem::GetInstance()->LoadMusic("sound/track1.mp3"); - if (bgMusic){ - JSoundSystem::GetInstance()->PlayMusic(bgMusic, true); - } - } - colorFilter = ALL_COLORS; - - mStage = STAGE_WELCOME; - - mRotation = 0; - mSlide = 0; - mAlpha = 255; - //mEngine->ResetPrivateVRAM(); - //mEngine->EnableVSync(true); - currentCard = NULL; - loadIndexes(currentCard); - last_user_activity = NO_USER_ACTIVITY_HELP_DELAY + 1; - onScreenTransition = 0; - - } - - - virtual void End() - { - //mEngine->EnableVSync(false); - if (bgMusic) JSoundSystem::GetInstance()->StopMusic(bgMusic); - SAFE_DELETE(backTex); - SAFE_DELETE(backQuad); - SAFE_DELETE(welcome_menu); - SAFE_DELETE(menu); - SAFE_DELETE(pspIconsTexture); - for (int i=0; i < 8; i++){ - delete pspIcons[i]; - } - SAFE_DELETE(myCollection); - SAFE_DELETE(myDeck); - SAFE_DELETE(pricelist); - SAFE_DELETE(playerdata); - } - - - void addRemove(MTGCard * card){ - if (!card) return; - if (displayed_deck->Remove(card)){ - if (displayed_deck == myCollection){ - myDeck->Add(card); - }else{ - myCollection->Add(card); - } - } - //loadIndexes(cardIndex[0]); - } - - int Remove(MTGCard * card){ - if (!card) return 0; - int result = displayed_deck->Remove(card); - loadIndexes(currentCard); - return result; - } - - - virtual void Update(float dt) - { - - hudAlpha = 255-(last_user_activity * 500); - if (hudAlpha < 0) hudAlpha = 0; - if (sellMenu){ - sellMenu->Update(dt); - return; - } - if (mStage == STAGE_WAITING || mStage == STAGE_ONSCREEN_MENU){ - if (mEngine->GetButtonState(PSP_CTRL_LEFT)){ - last_user_activity = 0; - currentCard = displayed_deck->getNext(currentCard,colorFilter); - mStage = STAGE_TRANSITION_LEFT; - } - - else if (mEngine->GetButtonState(PSP_CTRL_RIGHT)) - { - last_user_activity = 0; - currentCard = displayed_deck->getPrevious(currentCard,colorFilter); - mStage = STAGE_TRANSITION_RIGHT; - } - else if (mEngine->GetButtonState(PSP_CTRL_UP)) - { - last_user_activity = 0; - mStage = STAGE_TRANSITION_UP; - colorFilter --; - if (colorFilter < -1) colorFilter = MTG_COLOR_LAND; - } - - else if (mEngine->GetButtonState(PSP_CTRL_DOWN)) - { - last_user_activity = 0; - mStage = STAGE_TRANSITION_DOWN; - colorFilter ++; - if (colorFilter > MTG_COLOR_LAND) colorFilter =-1; - - } - else if (mEngine->GetButtonClick(PSP_CTRL_TRIANGLE) && last_user_activity > 0.2) - - { - last_user_activity = 0; - switchDisplay(); - - } - else if (mEngine->GetButtonClick(PSP_CTRL_CIRCLE)) - { - last_user_activity = 0; - addRemove(cardIndex[2]); - - } - else if (mEngine->GetButtonClick(PSP_CTRL_CROSS)) - { - last_user_activity = 0; - SAFE_DELETE(sellMenu); - char buffer[4096]; - MTGCard * card = cardIndex[2]; - if (card){ - int rnd = (rand() % 20); - price = pricelist->getPrice(card->getMTGId()) / 2; - price = price - price * (rnd -10)/100; - sprintf(buffer,"%s : %i credits",card->getName(),price); - sellMenu = NEW SimpleMenu(2,this,mFont,SCREEN_WIDTH-300,SCREEN_HEIGHT/2,270,buffer); - sellMenu->Add(20,"Yes"); - sellMenu->Add(21,"No"); - } - - } - else if (mEngine->GetButtonClick(PSP_CTRL_SQUARE)) - { - if (last_user_activity < NO_USER_ACTIVITY_HELP_DELAY){ - last_user_activity = NO_USER_ACTIVITY_HELP_DELAY + 1; - }else{ - last_user_activity = 0; - mStage = STAGE_WAITING; - } - - } - else if (mEngine->GetButtonClick(PSP_CTRL_START)) - { - mStage = STAGE_MENU; - - } - else{ - - if (last_user_activity > NO_USER_ACTIVITY_HELP_DELAY){ - if (mStage != STAGE_ONSCREEN_MENU){ - mStage = STAGE_ONSCREEN_MENU; - onScreenTransition = 1; - }else{ - if (onScreenTransition >0){ - onScreenTransition-= 0.05f; - }else{ - onScreenTransition = 0; - } - } - }else{ - last_user_activity+= dt; - } - - } - - }else if (mStage == STAGE_TRANSITION_RIGHT || mStage == STAGE_TRANSITION_LEFT) { - //mAlpha = 128; - if (mStage == STAGE_TRANSITION_RIGHT){ - mRotation -= 0.05f; - }else if(mStage == STAGE_TRANSITION_LEFT){ - mRotation += 0.05f; - } - if (fabs(mRotation) > 1.0f){ - rotateCards(mStage); - mRotation = 0; - mStage = STAGE_WAITING; - } - }else if (mStage == STAGE_TRANSITION_DOWN || mStage == STAGE_TRANSITION_UP){ - if (mStage == STAGE_TRANSITION_DOWN){ - mSlide -= 0.05f; - if (mSlide < -1.0f){ - loadIndexes(currentCard); - mSlide = 1; - }else if (mSlide > 0 && mSlide < 0.05){ - mStage = STAGE_WAITING; - mSlide = 0; - } - }else if (mStage == STAGE_TRANSITION_UP){ - mSlide += 0.05f; - if (mSlide > 1.0f){ - loadIndexes(currentCard); - mSlide = -1; - }else if (mSlide < 0 && mSlide > -0.05){ - mStage = STAGE_WAITING; - mSlide = 0; - } - } - - - }else if (mStage == STAGE_WELCOME){ - welcome_menu->Update(dt); - }else if (mStage == STAGE_MENU){ - menu->Update(dt); - } - - - } - - - void renderOnScreenBasicInfo(){ - char buffer[30], buffer2[30]; - - float y = 0; - JRenderer::GetInstance()->FillRoundRect(SCREEN_WIDTH-125,y-5,110,15,5,ARGB(128,0,0,0)); - sprintf(buffer, "DECK: %i", myDeck->getCount()); - mFont->DrawString(buffer, SCREEN_WIDTH-120 , y); - - if (colorFilter != ALL_COLORS){ - sprintf(buffer2, "( %i)", myDeck->getCount(colorFilter)); - mFont->DrawString(buffer2, SCREEN_WIDTH-55 , y); - JRenderer::GetInstance()->RenderQuad(mIcons[colorFilter], SCREEN_WIDTH-42 , y + 6 , 0.0f,0.5,0.5); - } - - } - - - void renderSlideBar(){ - int currentPos = displayed_deck->currentposition; - int total = displayed_deck->getCount(colorFilter); - int filler = 15; - int y = SCREEN_HEIGHT-25; - int bar_size = SCREEN_WIDTH - 2*filler; - int cursor_pos = bar_size * currentPos / total; - JRenderer * r = JRenderer::GetInstance(); - r->FillRoundRect(filler + 5,y+5,bar_size,0,3,ARGB(hudAlpha/2,0,0,0)); - r->DrawLine(filler+cursor_pos + 5 ,y+5,filler+cursor_pos + 5,y+10,ARGB(hudAlpha/2,0,0,0)); - - r->FillRoundRect(filler,y,bar_size,0,3,ARGB(hudAlpha/2,128,128,128)); - //r->FillCircle(filler+cursor_pos + 3 ,SCREEN_HEIGHT - 15 + 3,6,ARGB(255,128,128,128)); -r->DrawLine(filler+cursor_pos,y,filler+cursor_pos,y+5,ARGB(hudAlpha,255,255,255)); - char buffer[256]; - string deckname = "Collection"; - if (displayed_deck == myDeck){ - deckname = "Deck"; - } - sprintf(buffer,"%s - %i/%i", deckname.c_str(),currentPos, total); - mFont->SetColor(ARGB(hudAlpha,255,255,255)); - mFont->DrawString(buffer,SCREEN_WIDTH/2, y+5,JGETEXT_CENTER); - - - mFont->SetColor(ARGB(255,255,255,255)); - } - - void renderDeckBackground(){ - int max1 = 0; - int maxC1 = 4; - int max2 = 0; - int maxC2 = 4; - - for (int i= 0; i< MTG_NB_COLORS -1; i++){ - int value = myDeck->getCount(i); - if (value > max1){ - max2 = max1; - maxC2 = maxC1; - max1 = value; - maxC1 = i; - }else if (value > max2){ - max2 = value; - maxC2 = i; - } - } - if (max2 < max1/2){ - maxC2 = maxC1; - } - - int _a[6] = {255, 255, 255,255,255,255}; - int _r[6] = {75, 0, 0, 255,50,255}; - int _g[6] = {30, 255, 0, 0, 50,255}; - int _b[6] = {20, 0, 255,0, 50,255}; - - - PIXEL_TYPE colors[] = - { - ARGB(255,_r[maxC1],_g[maxC1],_b[maxC1]), - ARGB(255,_r[maxC1],_g[maxC1],_b[maxC1]), - ARGB(255,_r[maxC2],_g[maxC2],_b[maxC2]), - ARGB(255,_r[maxC2],_g[maxC2],_b[maxC2]), - }; - - JRenderer::GetInstance()->FillRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT,colors); - - } - - void renderOnScreenMenu(){ - mFont->SetColor(ARGB(255,255,255,255)); - JRenderer * r = JRenderer::GetInstance(); - float pspIconsSize = 0.5; - - float leftTransition = onScreenTransition*84; - float rightTransition = onScreenTransition*204; - float leftPspX = 40 - leftTransition; - float leftPspY = SCREEN_HEIGHT/2 - 30 ; - float rightPspX = SCREEN_WIDTH-100 + rightTransition; - float rightPspY = SCREEN_HEIGHT/2 - 30 ; - - - //FillRects - r->FillRect(0-(onScreenTransition*84),0,84,SCREEN_HEIGHT,ARGB(128,0,0,0)); - r->FillRect(SCREEN_WIDTH-204+(onScreenTransition*204),0,200,SCREEN_HEIGHT,ARGB(128,0,0,0)); - - - //LEFT PSP CIRCLE render - r->FillCircle(leftPspX,leftPspY,40,ARGB(128,50,50,50)); - - r->RenderQuad(pspIcons[0],leftPspX, leftPspY - 20,0,pspIconsSize,pspIconsSize); - r->RenderQuad(pspIcons[1],leftPspX, leftPspY + 20,0,pspIconsSize,pspIconsSize); - r->RenderQuad(pspIcons[2],leftPspX - 20, leftPspY,0,pspIconsSize,pspIconsSize); - r->RenderQuad(pspIcons[3],leftPspX + 20, leftPspY,0,pspIconsSize,pspIconsSize); - - - mFont->DrawString("Prev.", leftPspX - 35, leftPspY-15); - mFont->DrawString("Next", leftPspX + 15, leftPspY-15); - mFont->DrawString("card", leftPspX - 35, leftPspY); - mFont->DrawString("card", leftPspX + 15, leftPspY); - mFont->DrawString("Next color", leftPspX - 33, leftPspY - 35); - mFont->DrawString("Prev. color", leftPspX -33 , leftPspY +25); - - //RIGHT PSP CIRCLE render - r->FillCircle(rightPspX+(onScreenTransition*204),rightPspY,40,ARGB(128,50,50,50)); - r->RenderQuad(pspIcons[4],rightPspX+20, rightPspY,0,pspIconsSize,pspIconsSize); - r->RenderQuad(pspIcons[5],rightPspX, rightPspY - 20,0,pspIconsSize,pspIconsSize); - r->RenderQuad(pspIcons[6],rightPspX-20, rightPspY,0,pspIconsSize,pspIconsSize); - r->RenderQuad(pspIcons[7],rightPspX, rightPspY + 20,0,pspIconsSize,pspIconsSize); - - if (displayed_deck == myCollection){ - mFont->DrawString("Add card", rightPspX + 20, rightPspY-15); - mFont->DrawString("Display Deck", rightPspX - 35, rightPspY - 40); - }else{ - mFont->DrawString("Remove card", rightPspX + 20, rightPspY-15); - mFont->DrawString("Display Collection", rightPspX - 35, rightPspY - 40); - } - mFont->DrawString("Deck info", rightPspX - 70 , rightPspY-15); - mFont->DrawString("Sell card", rightPspX - 30 , rightPspY+20); - //Bottom menus - mFont->DrawString("menu", SCREEN_WIDTH-35 +rightTransition, SCREEN_HEIGHT-15); - - - - //Your Deck Information - char buffer[300]; - int nb_letters = 0; - for (int j=0; jgetCount(j); - if (value > 0){ - sprintf(buffer, "%i", value); - mFont->DrawString(buffer, SCREEN_WIDTH-190+rightTransition + nb_letters*13, SCREEN_HEIGHT/2 + 40); - r->RenderQuad(mIcons[j],SCREEN_WIDTH-197+rightTransition + nb_letters*13 , SCREEN_HEIGHT/2 + 46,0,0.5,0.5); - if (value > 9){nb_letters += 3;}else{nb_letters+=2;} - } - } - int value = myDeck->getCount(); - sprintf(buffer, "Your Deck: %i cards", value); - mFont->DrawString(buffer, SCREEN_WIDTH-200+rightTransition, SCREEN_HEIGHT/2 + 25); - - //TODO, put back ! - /*int nbCreatures = myDeck->countByType("Creature"); - int nbSpells = myDeck->countByType("Instant") + myDeck->countByType("Enchantment") + myDeck->countByType("Sorcery"); - - sprintf(buffer, "Creatures: %i - Spells: %i", nbCreatures, nbSpells); - mFont->DrawString(buffer, SCREEN_WIDTH-200+rightTransition, SCREEN_HEIGHT/2 + 55); - */ - - - mFont->DrawString("You are currently viewing your", SCREEN_WIDTH-200+rightTransition, 5); - if (displayed_deck == myCollection){ - mFont->DrawString("collection. Press TRIANGLE", SCREEN_WIDTH-200+rightTransition, 20); - mFont->DrawString("to switch to your deck", SCREEN_WIDTH-200+rightTransition, 35); - }else{ - mFont->DrawString("deck. Press TRIANGLE to", SCREEN_WIDTH-200+rightTransition, 20); - mFont->DrawString("switch to your collection", SCREEN_WIDTH-200+rightTransition, 35); - } - - } - - - virtual void renderCard(int id, float rotation){ - MTGCard * card = cardIndex[id]; - - - float max_scale = 0.96; - float min_scale = 0.2; - float x_center_0 = 180; - float right_border = SCREEN_WIDTH - 20 ; - - float x_center = x_center_0 + cos((rotation + 8 - id)*M_PI/12)*(right_border-x_center_0); - float scale = max_scale/ 1.12 * cos((x_center-x_center_0)*1.5/(right_border - x_center_0) ) + 0.2 * max_scale * cos (cos((x_center-x_center_0)*0.15/(right_border - x_center_0) )); - float x = x_center - 100*scale; - - float y = (SCREEN_HEIGHT - 285*scale)/2 + SCREEN_HEIGHT*mSlide*(scale+0.2); - - int alpha = (int) (255 * (scale + 1.0 - max_scale)); - - if (!card){ - /*int scaleBackup = mFont->GetScale(); - mFont->SetScale(scale); - mFont->DrawString("empty slot", x, y); - mFont->SetScale(scaleBackup);*/ - return; - } - JQuad * quad = backQuad; - - int showName = 1; - if (mParent->cache->isInCache(card) || last_user_activity > (abs(2-id) + 1)* NO_USER_ACTIVITY_SHOWCARD_DELAY){ - quad = card->getQuad(mParent->cache); - showName = 0; - } - - - - - if (quad){ - int quadAlpha = alpha; - if ( !displayed_deck->cards[card]) quadAlpha /=2; - quad->SetColor(ARGB(mAlpha,quadAlpha,quadAlpha,quadAlpha)); - JRenderer::GetInstance()->RenderQuad(quad, x , y , 0.0f,scale,scale); - if (showName){ - char buffer[4096]; - sprintf(buffer, "%s", card->getName()); - int scaleBackup = mFont->GetScale(); - mFont->SetScale(1*scale); - mFont->DrawString(buffer,x,y); - mFont->SetScale(scaleBackup); - } - }else{ - CardGui::alternateRender(card, mFont, mIcons, x_center, y + 142.5*scale, 0, scale); - } - if (last_user_activity < 3){ - int fontAlpha = alpha; - float qtY = y + 0 * scale; - float qtX = x + 120*scale; - char buffer[4096]; - sprintf(buffer, "x%i", displayed_deck->cards[card]); - JLBFont * font = menuFont; - int scaleBackup = font->GetScale(); - font->SetScale(1*scale); - font->SetColor(ARGB(fontAlpha/2,0,0,0)); - JRenderer::GetInstance()->FillRect(qtX, qtY,32*scale,20*scale,ARGB(fontAlpha/2,0,0,0)); - font->DrawString(buffer, qtX + 2, qtY + 2); - font->SetColor(ARGB(fontAlpha,255,255,255)); - font->DrawString(buffer, qtX, qtY); - font->SetScale(scaleBackup); - font->SetColor(ARGB(255,255,255,255)); - } - } - - - virtual void renderCard (int id){ - renderCard(id, 0); - } - - virtual void Render() - { - // void RenderQuad(JQuad* quad, float xo, float yo, float angle=0.0f, float xScale=1.0f, float yScale=1.0f); - - JRenderer::GetInstance()->ClearScreen(ARGB(0,0,0,0)); - - - if(displayed_deck == myDeck){ - renderDeckBackground(); - } - - - - - int order[3] = {1,2,3}; - if (mRotation < 0.5 && mRotation > -0.5){ - order[1]=3; - order[2]=2; - }else if (mRotation < -0.5){ - order[0] = 3; - order[2] = 1; - } - - renderCard(6,mRotation); - renderCard(5,mRotation); - renderCard(4,mRotation); - renderCard(0,mRotation); - - for (int i =0; i< 3; i++){ - renderCard(order[i],mRotation); - } - - if (displayed_deck->getCount(colorFilter)>0){ - renderSlideBar(); - }else{ - int scaleBackup = mFont->GetScale(); - mFont->SetScale(2); - mFont->DrawString("No Card", SCREEN_WIDTH/2, SCREEN_HEIGHT/2,JGETEXT_CENTER); - mFont->SetScale(scaleBackup); - } - - if (mStage == STAGE_ONSCREEN_MENU){ - renderOnScreenMenu(); - }else if (mStage == STAGE_WELCOME){ - welcome_menu->Render(); - }else{ - renderOnScreenBasicInfo(); - if (sellMenu) sellMenu->Render(); - } - if (mStage == STAGE_MENU){ - menu->Render(); - } - - } - - - int loadDeck(int deckid){ - SAFE_DELETE(myCollection); - myCollection = NEW DeckDataWrapper(NEW MTGDeck("Res/player/collection.dat", mParent->cache,mParent->collection)); - displayed_deck = myCollection; - char filename[4096]; - sprintf(filename, "Res/player/deck%i.txt", deckid); - SAFE_DELETE(myDeck); - myDeck = NEW DeckDataWrapper(NEW MTGDeck(filename, mParent->cache,mParent->collection)); - MTGCard * current = myDeck->getNext(); - while (current){ - int howmanyinDeck = myDeck->cards[current]; - for (int i = 0; i < howmanyinDeck; i++){ - int deleted = myCollection->Remove(current); - if (!deleted){ - myDeck->Remove(current); - } - } - current = myDeck->getNext(current); - } - return 1; - } - -virtual void ButtonPressed(int controllerId, int controlId) - { - switch (controlId) - { - case 1: - case 2: - case 3: - case 4: - case 5: - loadDeck(controlId); - mStage = STAGE_WAITING; - break; - case 10: - mParent->SetNextState(GAME_STATE_MENU); - break; - case 11: - myDeck->save(); - playerdata->save(); - pricelist->save(); - mStage = STAGE_WAITING; - break; - case 12: - mParent->SetNextState(GAME_STATE_MENU); - break; - case 13: - mStage = STAGE_WAITING; - break; - case 20: - { - MTGCard * card = cardIndex[2]; - if (card){ - int rnd = (rand() % 20); - price = price - (rnd * price)/100; - playerdata->credits += price; - pricelist->setPrice(card->getMTGId(),price*2); - #if defined (WIN32) || defined (LINUX) - char buf[4096]; - sprintf(buf, "CARD'S NAME : %s", card->getName()); - OutputDebugString(buf); - #endif - playerdata->collection->remove(card->getMTGId()); - Remove(card); - } - } - case 21: - SAFE_DELETE(sellMenu); - break; - } - -} - -}; - - - - -#endif - +#ifndef _GAME_STATE_DECK_VIEWER_H_ +#define _GAME_STATE_DECK_VIEWER_H_ + +#include +#include + +#include + +#include "GameState.h" +#include "SimpleMenu.h" +#include "../include/CardGui.h" +#include "../include/GameOptions.h" +#include "../include/PriceList.h" +#include "../include/PlayerData.h" +#include "../include/DeckDataWrapper.h" + +#define NO_USER_ACTIVITY_HELP_DELAY 10 +#define NO_USER_ACTIVITY_SHOWCARD_DELAY 0.1 + +#define STAGE_WAITING 2 +#define STAGE_TRANSITION_LEFT 1 +#define STAGE_TRANSITION_RIGHT 0 +#define STAGE_TRANSITION_UP 3 +#define STAGE_TRANSITION_DOWN 4 +#define STAGE_ONSCREEN_MENU 5 +#define STAGE_WELCOME 6 +#define STAGE_MENU 7 + + +#define ALL_COLORS -1 + +#define ROTATE_LEFT 1; +#define ROTATE_RIGHT 0; + + + + +class GameStateDeckViewer: public GameState, public JGuiListener +{ + private: + JQuad * mIcons[7]; + JQuad * pspIcons[8]; + JTexture * pspIconsTexture; + float last_user_activity; + float onScreenTransition; + float mRotation; + float mSlide; + int mAlpha; + int mStage; + + int colorFilter; + JMusic * bgMusic; + JTexture * backTex; + JQuad * backQuad; + SimpleMenu * welcome_menu; + JLBFont * mFont; + bool showing_user_deck; + JLBFont * menuFont; + SimpleMenu * menu; + SimpleMenu * sellMenu; + PriceList* pricelist; + PlayerData * playerdata; + int price; + DeckDataWrapper * displayed_deck; + DeckDataWrapper * myDeck; + DeckDataWrapper * myCollection; + MTGCard * currentCard; + MTGCard * cardIndex[7]; + int hudAlpha; + public: + + GameStateDeckViewer(GameApp* parent): GameState(parent) { + bgMusic = NULL; + } + virtual ~GameStateDeckViewer() { + SAFE_DELETE(bgMusic); + } + + + void rotateCards(int direction){ + int maxCards=displayed_deck->getCount(colorFilter); + if (maxCards==0) + return; + int left = direction; + if (left){ + MTGCard * currentCard = displayed_deck->getNext(cardIndex[6],colorFilter); + for (int i = 1; i<7; i++){ + cardIndex[i-1] = cardIndex[i]; + } + cardIndex[6] = currentCard; + }else{ + MTGCard * currentCard = displayed_deck->getPrevious(cardIndex[0],colorFilter); + for (int i = 5; i>=0; i--){ + cardIndex[i+1] = cardIndex[i]; + } + cardIndex[0] = currentCard; + } + displayed_deck->updateCurrentPosition(cardIndex[2],colorFilter); + } + + void loadIndexes(MTGCard * current = NULL){ + for (int i = 0; i < 7; i++){ + cardIndex[i] = NULL; + } + MTGCard * _current = current; + _current = displayed_deck->getNext(NULL,colorFilter); + for (int i = 0; i < 7; i++){ + cardIndex[i] = _current; +#if defined (WIN32) || defined (LINUX) + char buf[4096]; + sprintf(buf,"Loadindexes[%i] is NULL\n", i); + if(_current) sprintf(buf, "LoadIndexes[%i] : %s\n", i, _current->getName()); + OutputDebugString(buf); +#endif + _current = displayed_deck->getNext(_current,colorFilter); + + } + displayed_deck->updateCurrentPosition(cardIndex[2],colorFilter); + } + + void switchDisplay(){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("Switching display"); +#endif + if (displayed_deck == myCollection){ + displayed_deck = myDeck; + }else{ + displayed_deck = myCollection; + } + currentCard = NULL; + loadIndexes(); + } + + virtual void Start() + { + hudAlpha = 0; + pricelist = NEW PriceList("Res/settings/prices.dat",mParent->collection); + playerdata = NEW PlayerData(mParent->collection); + sellMenu = NULL; + myCollection = NEW DeckDataWrapper(NEW MTGDeck("Res/player/collection.dat", mParent->cache,mParent->collection)); + displayed_deck = myCollection; + myDeck = NULL; + menuFont = GameApp::CommonRes->GetJLBFont("graphics/f3"); + mFont = GameApp::CommonRes->GetJLBFont("graphics/magic"); + + + + + menu = NEW SimpleMenu(11,this,menuFont,SCREEN_WIDTH/2-100,20,200); + menu->Add(11,"Save"); + menu->Add(12,"Back to main menu"); + menu->Add(13, "Cancel"); + + + //icon images + mIcons[MTG_COLOR_ARTIFACT] = GameApp::CommonRes->GetQuad("c_artifact"); + mIcons[MTG_COLOR_LAND] = GameApp::CommonRes->GetQuad("c_land"); + mIcons[MTG_COLOR_WHITE] = GameApp::CommonRes->GetQuad("c_white"); + mIcons[MTG_COLOR_RED] = GameApp::CommonRes->GetQuad("c_red"); + mIcons[MTG_COLOR_BLACK] = GameApp::CommonRes->GetQuad("c_black"); + mIcons[MTG_COLOR_BLUE] = GameApp::CommonRes->GetQuad("c_blue"); + mIcons[MTG_COLOR_GREEN] = GameApp::CommonRes->GetQuad("c_green"); + for (int i=0; i < 7; i++){ + mIcons[i]->SetHotSpot(16,16); + } + + + pspIconsTexture = JRenderer::GetInstance()->LoadTexture("graphics/iconspsp.png", TEX_TYPE_USE_VRAM); + + for (int i=0; i < 8; i++){ + pspIcons[i] = NEW JQuad(pspIconsTexture, i*32, 0, 32, 32); + pspIcons[i]->SetHotSpot(16,16); + } + + + backTex = JRenderer::GetInstance()->LoadTexture("sets/back.jpg", TEX_TYPE_USE_VRAM); + backQuad = NEW JQuad(backTex, 0, 0, 200, 285); // Create quad for rendering. + + //menuFont = NEW JLBFont("graphics/f3",16); + menuFont = GameApp::CommonRes->GetJLBFont("graphics/f3"); + welcome_menu = NEW SimpleMenu(10,this,menuFont,20,20,200); + char buffer[100]; + for (int i=1; i < 6; i++){ + sprintf(buffer, "Res/player/deck%i.txt",i); + std::ifstream file(buffer); + if(file){ + welcome_menu->Add(i, GameState::menuTexts[i]); + file.close(); + }else{ + welcome_menu->Add(i, GameState::menuTexts[0]); + } + + } + welcome_menu->Add(10, "Cancel"); + + if (GameApp::HasMusic && GameOptions::GetInstance()->values[OPTIONS_MUSICVOLUME] > 0){ + if (!bgMusic) bgMusic = JSoundSystem::GetInstance()->LoadMusic("sound/track1.mp3"); + if (bgMusic){ + JSoundSystem::GetInstance()->PlayMusic(bgMusic, true); + } + } + colorFilter = ALL_COLORS; + + mStage = STAGE_WELCOME; + + mRotation = 0; + mSlide = 0; + mAlpha = 255; + //mEngine->ResetPrivateVRAM(); + //mEngine->EnableVSync(true); + currentCard = NULL; + loadIndexes(currentCard); + last_user_activity = NO_USER_ACTIVITY_HELP_DELAY + 1; + onScreenTransition = 0; + + } + + + virtual void End() + { + //mEngine->EnableVSync(false); + if (bgMusic) JSoundSystem::GetInstance()->StopMusic(bgMusic); + SAFE_DELETE(backTex); + SAFE_DELETE(backQuad); + SAFE_DELETE(welcome_menu); + SAFE_DELETE(menu); + SAFE_DELETE(pspIconsTexture); + for (int i=0; i < 8; i++){ + delete pspIcons[i]; + } + SAFE_DELETE(myCollection); + SAFE_DELETE(myDeck); + SAFE_DELETE(pricelist); + SAFE_DELETE(playerdata); + } + + + void addRemove(MTGCard * card){ + if (!card) return; + if (displayed_deck->Remove(card)){ + if (displayed_deck == myCollection){ + myDeck->Add(card); + }else{ + myCollection->Add(card); + } + } + //loadIndexes(cardIndex[0]); + } + + int Remove(MTGCard * card){ + if (!card) return 0; + int result = displayed_deck->Remove(card); + loadIndexes(currentCard); + return result; + } + + + virtual void Update(float dt) + { + + hudAlpha = 255-(last_user_activity * 500); + if (hudAlpha < 0) hudAlpha = 0; + if (sellMenu){ + sellMenu->Update(dt); + return; + } + if (mStage == STAGE_WAITING || mStage == STAGE_ONSCREEN_MENU){ + if (mEngine->GetButtonClick(PSP_CTRL_LEFT)){ + last_user_activity = 0; + currentCard = displayed_deck->getNext(currentCard,colorFilter); + mStage = STAGE_TRANSITION_LEFT; + } + + else if (mEngine->GetButtonClick(PSP_CTRL_RIGHT)) + { + last_user_activity = 0; + currentCard = displayed_deck->getPrevious(currentCard,colorFilter); + mStage = STAGE_TRANSITION_RIGHT; + } + else if (mEngine->GetButtonClick(PSP_CTRL_UP)) + { + last_user_activity = 0; + mStage = STAGE_TRANSITION_UP; + colorFilter --; + if (colorFilter < -1) colorFilter = MTG_COLOR_LAND; + } + + else if (mEngine->GetButtonClick(PSP_CTRL_DOWN)) + { + last_user_activity = 0; + mStage = STAGE_TRANSITION_DOWN; + colorFilter ++; + if (colorFilter > MTG_COLOR_LAND) colorFilter =-1; + + } + else if (mEngine->GetButtonClick(PSP_CTRL_TRIANGLE) && last_user_activity > 0.2) + + { + last_user_activity = 0; + switchDisplay(); + + } + else if (mEngine->GetButtonClick(PSP_CTRL_CIRCLE)) + { + last_user_activity = 0; + addRemove(cardIndex[2]); + + } + else if (mEngine->GetButtonClick(PSP_CTRL_CROSS)) + { + last_user_activity = 0; + SAFE_DELETE(sellMenu); + char buffer[4096]; + MTGCard * card = cardIndex[2]; + if (card){ + int rnd = (rand() % 20); + price = pricelist->getPrice(card->getMTGId()) / 2; + price = price - price * (rnd -10)/100; + sprintf(buffer,"%s : %i credits",card->getName(),price); + sellMenu = NEW SimpleMenu(2,this,mFont,SCREEN_WIDTH-300,SCREEN_HEIGHT/2,270,buffer); + sellMenu->Add(20,"Yes"); + sellMenu->Add(21,"No"); + } + + } + else if (mEngine->GetButtonClick(PSP_CTRL_SQUARE)) + { + if (last_user_activity < NO_USER_ACTIVITY_HELP_DELAY){ + last_user_activity = NO_USER_ACTIVITY_HELP_DELAY + 1; + }else{ + last_user_activity = 0; + mStage = STAGE_WAITING; + } + + } + else if (mEngine->GetButtonClick(PSP_CTRL_START)) + { + mStage = STAGE_MENU; + + } + else{ + + if (last_user_activity > NO_USER_ACTIVITY_HELP_DELAY){ + if (mStage != STAGE_ONSCREEN_MENU){ + mStage = STAGE_ONSCREEN_MENU; + onScreenTransition = 1; + }else{ + if (onScreenTransition >0){ + onScreenTransition-= 0.05f; + }else{ + onScreenTransition = 0; + } + } + }else{ + last_user_activity+= dt; + } + + } + + }else if (mStage == STAGE_TRANSITION_RIGHT || mStage == STAGE_TRANSITION_LEFT) { + //mAlpha = 128; + if (mStage == STAGE_TRANSITION_RIGHT){ + mRotation -= 0.05f; + }else if(mStage == STAGE_TRANSITION_LEFT){ + mRotation += 0.05f; + } + if (fabs(mRotation) > 1.0f){ + rotateCards(mStage); + mRotation = 0; + mStage = STAGE_WAITING; + } + }else if (mStage == STAGE_TRANSITION_DOWN || mStage == STAGE_TRANSITION_UP){ + if (mStage == STAGE_TRANSITION_DOWN){ + mSlide -= 0.05f; + if (mSlide < -1.0f){ + loadIndexes(currentCard); + mSlide = 1; + }else if (mSlide > 0 && mSlide < 0.05){ + mStage = STAGE_WAITING; + mSlide = 0; + } + }else if (mStage == STAGE_TRANSITION_UP){ + mSlide += 0.05f; + if (mSlide > 1.0f){ + loadIndexes(currentCard); + mSlide = -1; + }else if (mSlide < 0 && mSlide > -0.05){ + mStage = STAGE_WAITING; + mSlide = 0; + } + } + + + }else if (mStage == STAGE_WELCOME){ + welcome_menu->Update(dt); + }else if (mStage == STAGE_MENU){ + menu->Update(dt); + } + + + } + + + void renderOnScreenBasicInfo(){ + char buffer[30], buffer2[30]; + + float y = 0; + JRenderer::GetInstance()->FillRoundRect(SCREEN_WIDTH-125,y-5,110,15,5,ARGB(128,0,0,0)); + sprintf(buffer, "DECK: %i", myDeck->getCount()); + mFont->DrawString(buffer, SCREEN_WIDTH-120 , y); + + if (colorFilter != ALL_COLORS){ + sprintf(buffer2, "( %i)", myDeck->getCount(colorFilter)); + mFont->DrawString(buffer2, SCREEN_WIDTH-55 , y); + JRenderer::GetInstance()->RenderQuad(mIcons[colorFilter], SCREEN_WIDTH-42 , y + 6 , 0.0f,0.5,0.5); + } + + } + + + void renderSlideBar(){ + int currentPos = displayed_deck->currentposition; + int total = displayed_deck->getCount(colorFilter); + int filler = 15; + int y = SCREEN_HEIGHT-25; + int bar_size = SCREEN_WIDTH - 2*filler; + int cursor_pos = bar_size * currentPos / total; + JRenderer * r = JRenderer::GetInstance(); + r->FillRoundRect(filler + 5,y+5,bar_size,0,3,ARGB(hudAlpha/2,0,0,0)); + r->DrawLine(filler+cursor_pos + 5 ,y+5,filler+cursor_pos + 5,y+10,ARGB(hudAlpha/2,0,0,0)); + + r->FillRoundRect(filler,y,bar_size,0,3,ARGB(hudAlpha/2,128,128,128)); + //r->FillCircle(filler+cursor_pos + 3 ,SCREEN_HEIGHT - 15 + 3,6,ARGB(255,128,128,128)); + r->DrawLine(filler+cursor_pos,y,filler+cursor_pos,y+5,ARGB(hudAlpha,255,255,255)); + char buffer[256]; + string deckname = "Collection"; + if (displayed_deck == myDeck){ + deckname = "Deck"; + } + sprintf(buffer,"%s - %i/%i", deckname.c_str(),currentPos, total); + mFont->SetColor(ARGB(hudAlpha,255,255,255)); + mFont->DrawString(buffer,SCREEN_WIDTH/2, y+5,JGETEXT_CENTER); + + + mFont->SetColor(ARGB(255,255,255,255)); + } + + void renderDeckBackground(){ + int max1 = 0; + int maxC1 = 4; + int max2 = 0; + int maxC2 = 4; + + for (int i= 0; i< MTG_NB_COLORS -1; i++){ + int value = myDeck->getCount(i); + if (value > max1){ + max2 = max1; + maxC2 = maxC1; + max1 = value; + maxC1 = i; + }else if (value > max2){ + max2 = value; + maxC2 = i; + } + } + if (max2 < max1/2){ + maxC2 = maxC1; + } + + int _a[6] = {255, 255, 255,255,255,255}; + int _r[6] = {75, 0, 0, 255,50,255}; + int _g[6] = {30, 255, 0, 0, 50,255}; + int _b[6] = {20, 0, 255,0, 50,255}; + + + PIXEL_TYPE colors[] = + { + ARGB(255,_r[maxC1],_g[maxC1],_b[maxC1]), + ARGB(255,_r[maxC1],_g[maxC1],_b[maxC1]), + ARGB(255,_r[maxC2],_g[maxC2],_b[maxC2]), + ARGB(255,_r[maxC2],_g[maxC2],_b[maxC2]), + }; + + JRenderer::GetInstance()->FillRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT,colors); + + } + + void renderOnScreenMenu(){ + mFont->SetColor(ARGB(255,255,255,255)); + JRenderer * r = JRenderer::GetInstance(); + float pspIconsSize = 0.5; + + float leftTransition = onScreenTransition*84; + float rightTransition = onScreenTransition*204; + float leftPspX = 40 - leftTransition; + float leftPspY = SCREEN_HEIGHT/2 - 30 ; + float rightPspX = SCREEN_WIDTH-100 + rightTransition; + float rightPspY = SCREEN_HEIGHT/2 - 30 ; + + + //FillRects + r->FillRect(0-(onScreenTransition*84),0,84,SCREEN_HEIGHT,ARGB(128,0,0,0)); + r->FillRect(SCREEN_WIDTH-204+(onScreenTransition*204),0,200,SCREEN_HEIGHT,ARGB(128,0,0,0)); + + + //LEFT PSP CIRCLE render + r->FillCircle(leftPspX,leftPspY,40,ARGB(128,50,50,50)); + + r->RenderQuad(pspIcons[0],leftPspX, leftPspY - 20,0,pspIconsSize,pspIconsSize); + r->RenderQuad(pspIcons[1],leftPspX, leftPspY + 20,0,pspIconsSize,pspIconsSize); + r->RenderQuad(pspIcons[2],leftPspX - 20, leftPspY,0,pspIconsSize,pspIconsSize); + r->RenderQuad(pspIcons[3],leftPspX + 20, leftPspY,0,pspIconsSize,pspIconsSize); + + + mFont->DrawString("Prev.", leftPspX - 35, leftPspY-15); + mFont->DrawString("Next", leftPspX + 15, leftPspY-15); + mFont->DrawString("card", leftPspX - 35, leftPspY); + mFont->DrawString("card", leftPspX + 15, leftPspY); + mFont->DrawString("Next color", leftPspX - 33, leftPspY - 35); + mFont->DrawString("Prev. color", leftPspX -33 , leftPspY +25); + + //RIGHT PSP CIRCLE render + r->FillCircle(rightPspX+(onScreenTransition*204),rightPspY,40,ARGB(128,50,50,50)); + r->RenderQuad(pspIcons[4],rightPspX+20, rightPspY,0,pspIconsSize,pspIconsSize); + r->RenderQuad(pspIcons[5],rightPspX, rightPspY - 20,0,pspIconsSize,pspIconsSize); + r->RenderQuad(pspIcons[6],rightPspX-20, rightPspY,0,pspIconsSize,pspIconsSize); + r->RenderQuad(pspIcons[7],rightPspX, rightPspY + 20,0,pspIconsSize,pspIconsSize); + + if (displayed_deck == myCollection){ + mFont->DrawString("Add card", rightPspX + 20, rightPspY-15); + mFont->DrawString("Display Deck", rightPspX - 35, rightPspY - 40); + }else{ + mFont->DrawString("Remove card", rightPspX + 20, rightPspY-15); + mFont->DrawString("Display Collection", rightPspX - 35, rightPspY - 40); + } + mFont->DrawString("Deck info", rightPspX - 70 , rightPspY-15); + mFont->DrawString("Sell card", rightPspX - 30 , rightPspY+20); + //Bottom menus + mFont->DrawString("menu", SCREEN_WIDTH-35 +rightTransition, SCREEN_HEIGHT-15); + + + + //Your Deck Information + char buffer[300]; + int nb_letters = 0; + for (int j=0; jgetCount(j); + if (value > 0){ + sprintf(buffer, "%i", value); + mFont->DrawString(buffer, SCREEN_WIDTH-190+rightTransition + nb_letters*13, SCREEN_HEIGHT/2 + 40); + r->RenderQuad(mIcons[j],SCREEN_WIDTH-197+rightTransition + nb_letters*13 , SCREEN_HEIGHT/2 + 46,0,0.5,0.5); + if (value > 9){nb_letters += 3;}else{nb_letters+=2;} + } + } + int value = myDeck->getCount(); + sprintf(buffer, "Your Deck: %i cards", value); + mFont->DrawString(buffer, SCREEN_WIDTH-200+rightTransition, SCREEN_HEIGHT/2 + 25); + + //TODO, put back ! + /*int nbCreatures = myDeck->countByType("Creature"); + int nbSpells = myDeck->countByType("Instant") + myDeck->countByType("Enchantment") + myDeck->countByType("Sorcery"); + + sprintf(buffer, "Creatures: %i - Spells: %i", nbCreatures, nbSpells); + mFont->DrawString(buffer, SCREEN_WIDTH-200+rightTransition, SCREEN_HEIGHT/2 + 55); + */ + + + mFont->DrawString("You are currently viewing your", SCREEN_WIDTH-200+rightTransition, 5); + if (displayed_deck == myCollection){ + mFont->DrawString("collection. Press TRIANGLE", SCREEN_WIDTH-200+rightTransition, 20); + mFont->DrawString("to switch to your deck", SCREEN_WIDTH-200+rightTransition, 35); + }else{ + mFont->DrawString("deck. Press TRIANGLE to", SCREEN_WIDTH-200+rightTransition, 20); + mFont->DrawString("switch to your collection", SCREEN_WIDTH-200+rightTransition, 35); + } + + } + + + virtual void renderCard(int id, float rotation){ + MTGCard * card = cardIndex[id]; + + + float max_scale = 0.96; + float min_scale = 0.2; + float x_center_0 = 180; + float right_border = SCREEN_WIDTH - 20 ; + + float x_center = x_center_0 + cos((rotation + 8 - id)*M_PI/12)*(right_border-x_center_0); + float scale = max_scale/ 1.12 * cos((x_center-x_center_0)*1.5/(right_border - x_center_0) ) + 0.2 * max_scale * cos (cos((x_center-x_center_0)*0.15/(right_border - x_center_0) )); + float x = x_center - 100*scale; + + float y = (SCREEN_HEIGHT - 285*scale)/2 + SCREEN_HEIGHT*mSlide*(scale+0.2); + + int alpha = (int) (255 * (scale + 1.0 - max_scale)); + + if (!card){ + /*int scaleBackup = mFont->GetScale(); + mFont->SetScale(scale); + mFont->DrawString("empty slot", x, y); + mFont->SetScale(scaleBackup);*/ + return; + } + JQuad * quad = backQuad; + + int showName = 1; + if (mParent->cache->isInCache(card) || last_user_activity > (abs(2-id) + 1)* NO_USER_ACTIVITY_SHOWCARD_DELAY){ + quad = card->getQuad(mParent->cache); + showName = 0; + } + + + + + if (quad){ + int quadAlpha = alpha; + if ( !displayed_deck->cards[card]) quadAlpha /=2; + quad->SetColor(ARGB(mAlpha,quadAlpha,quadAlpha,quadAlpha)); + JRenderer::GetInstance()->RenderQuad(quad, x , y , 0.0f,scale,scale); + if (showName){ + char buffer[4096]; + sprintf(buffer, "%s", card->getName()); + int scaleBackup = mFont->GetScale(); + mFont->SetScale(1*scale); + mFont->DrawString(buffer,x,y); + mFont->SetScale(scaleBackup); + } + }else{ + CardGui::alternateRender(card, mFont, mIcons, x_center, y + 142.5*scale, 0, scale); + } + if (last_user_activity < 3){ + int fontAlpha = alpha; + float qtY = y + 0 * scale; + float qtX = x + 120*scale; + char buffer[4096]; + sprintf(buffer, "x%i", displayed_deck->cards[card]); + JLBFont * font = menuFont; + int scaleBackup = font->GetScale(); + font->SetScale(1*scale); + font->SetColor(ARGB(fontAlpha/2,0,0,0)); + JRenderer::GetInstance()->FillRect(qtX, qtY,32*scale,20*scale,ARGB(fontAlpha/2,0,0,0)); + font->DrawString(buffer, qtX + 2, qtY + 2); + font->SetColor(ARGB(fontAlpha,255,255,255)); + font->DrawString(buffer, qtX, qtY); + font->SetScale(scaleBackup); + font->SetColor(ARGB(255,255,255,255)); + } + } + + + virtual void renderCard (int id){ + renderCard(id, 0); + } + + virtual void Render() + { + // void RenderQuad(JQuad* quad, float xo, float yo, float angle=0.0f, float xScale=1.0f, float yScale=1.0f); + + JRenderer::GetInstance()->ClearScreen(ARGB(0,0,0,0)); + + + if(displayed_deck == myDeck){ + renderDeckBackground(); + } + + + + + int order[3] = {1,2,3}; + if (mRotation < 0.5 && mRotation > -0.5){ + order[1]=3; + order[2]=2; + }else if (mRotation < -0.5){ + order[0] = 3; + order[2] = 1; + } + + renderCard(6,mRotation); + renderCard(5,mRotation); + renderCard(4,mRotation); + renderCard(0,mRotation); + + for (int i =0; i< 3; i++){ + renderCard(order[i],mRotation); + } + + if (displayed_deck->getCount(colorFilter)>0){ + renderSlideBar(); + }else{ + int scaleBackup = mFont->GetScale(); + mFont->SetScale(2); + mFont->DrawString("No Card", SCREEN_WIDTH/2, SCREEN_HEIGHT/2,JGETEXT_CENTER); + mFont->SetScale(scaleBackup); + } + + if (mStage == STAGE_ONSCREEN_MENU){ + renderOnScreenMenu(); + }else if (mStage == STAGE_WELCOME){ + welcome_menu->Render(); + }else{ + renderOnScreenBasicInfo(); + if (sellMenu) sellMenu->Render(); + } + if (mStage == STAGE_MENU){ + menu->Render(); + } + + } + + + int loadDeck(int deckid){ + SAFE_DELETE(myCollection); + myCollection = NEW DeckDataWrapper(NEW MTGDeck("Res/player/collection.dat", mParent->cache,mParent->collection)); + displayed_deck = myCollection; + char filename[4096]; + sprintf(filename, "Res/player/deck%i.txt", deckid); + SAFE_DELETE(myDeck); + myDeck = NEW DeckDataWrapper(NEW MTGDeck(filename, mParent->cache,mParent->collection)); + MTGCard * current = myDeck->getNext(); + while (current){ + int howmanyinDeck = myDeck->cards[current]; + for (int i = 0; i < howmanyinDeck; i++){ + int deleted = myCollection->Remove(current); + if (!deleted){ + myDeck->Remove(current); + } + } + current = myDeck->getNext(current); + } + return 1; + } + + virtual void ButtonPressed(int controllerId, int controlId) + { + switch (controlId) + { + case 1: + case 2: + case 3: + case 4: + case 5: + loadDeck(controlId); + mStage = STAGE_WAITING; + break; + case 10: + mParent->SetNextState(GAME_STATE_MENU); + break; + case 11: + myDeck->save(); + playerdata->save(); + pricelist->save(); + mStage = STAGE_WAITING; + break; + case 12: + mParent->SetNextState(GAME_STATE_MENU); + break; + case 13: + mStage = STAGE_WAITING; + break; + case 20: + { + MTGCard * card = cardIndex[2]; + if (card){ + int rnd = (rand() % 20); + price = price - (rnd * price)/100; + playerdata->credits += price; + pricelist->setPrice(card->getMTGId(),price*2); +#if defined (WIN32) || defined (LINUX) + char buf[4096]; + sprintf(buf, "CARD'S NAME : %s", card->getName()); + OutputDebugString(buf); +#endif + playerdata->collection->remove(card->getMTGId()); + Remove(card); + } + } + case 21: + SAFE_DELETE(sellMenu); + break; + } + + } + +}; + + + + +#endif + diff --git a/projects/mtg/include/GameStateDuel.h b/projects/mtg/include/GameStateDuel.h index 7060cb618..bd07b5d9d 100644 --- a/projects/mtg/include/GameStateDuel.h +++ b/projects/mtg/include/GameStateDuel.h @@ -1,55 +1,55 @@ -#ifndef _GAME_STATE_DUEL_H_ -#define _GAME_STATE_DUEL_H_ - - -#include "../include/GameState.h" -#include "_includeAll.h" -#include "../include/SimpleMenu.h" - - -#define DUEL_START 0 -#define DUEL_END 1 -#define DUEL_CHOOSE_DECK1 2 -#define DUEL_CHOOSE_DECK2 3 -#define ERROR_NO_DECK 4 -#define DUEL_PLAY 5 -#define DUEL_MENU 6 - - -#ifdef TESTSUITE -class TestSuite; -#endif - -class GameStateDuel: public GameState, public JGuiListener -{ -private: -#ifdef TESTSUITE - TestSuite * testSuite; -#endif - int mGamePhase; - Player * mCurrentPlayer; - Player * mPlayers[2]; - MTGPlayerCards * deck[2]; - GameObserver * game; - SimpleMenu * deckmenu; - SimpleMenu * menu; - JLBFont* mFont; - - void loadPlayer(int playerId, int decknb = 0); -public: - GameStateDuel(GameApp* parent); - virtual ~GameStateDuel(); +#ifndef _GAME_STATE_DUEL_H_ +#define _GAME_STATE_DUEL_H_ + + +#include "../include/GameState.h" +#include "_includeAll.h" +#include "../include/SimpleMenu.h" + + +#define DUEL_START 0 +#define DUEL_END 1 +#define DUEL_CHOOSE_DECK1 2 +#define DUEL_CHOOSE_DECK2 3 +#define ERROR_NO_DECK 4 +#define DUEL_PLAY 5 +#define DUEL_MENU 6 + + #ifdef TESTSUITE - void loadTestSuitePlayers(); -#endif - virtual void ButtonPressed(int ControllerId, int ControlId); - virtual void Start(); - virtual void End(); - virtual void Update(float dt); - virtual void Render(); - -}; - - -#endif - +class TestSuite; +#endif + +class GameStateDuel: public GameState, public JGuiListener +{ + private: +#ifdef TESTSUITE + TestSuite * testSuite; +#endif + int mGamePhase; + Player * mCurrentPlayer; + Player * mPlayers[2]; + MTGPlayerCards * deck[2]; + GameObserver * game; + SimpleMenu * deckmenu; + SimpleMenu * menu; + JLBFont* mFont; + + void loadPlayer(int playerId, int decknb = 0); + public: + GameStateDuel(GameApp* parent); + virtual ~GameStateDuel(); +#ifdef TESTSUITE + void loadTestSuitePlayers(); +#endif + virtual void ButtonPressed(int ControllerId, int ControlId); + virtual void Start(); + virtual void End(); + virtual void Update(float dt); + virtual void Render(); + +}; + + +#endif + diff --git a/projects/mtg/include/GameStateMenu.h b/projects/mtg/include/GameStateMenu.h index b14ca5035..c138e2c8a 100644 --- a/projects/mtg/include/GameStateMenu.h +++ b/projects/mtg/include/GameStateMenu.h @@ -1,432 +1,432 @@ -#ifndef _GAME_STATE_MENU_H_ -#define _GAME_STATE_MENU_H_ - -#include -#include - -#include "GameState.h" -#include "MenuItem.h" -#include "SimpleMenu.h" - -#include "../include/GameOptions.h" - - - -#define STATE_MENU 0 -#define STATE_SUBMENU 1 -#define STATE_LOADING_MENU 2 -#define STATE_LOADING_CARDS 3 -#define STATE_FIRST_TIME 4 -#define STATE_WARNING 5 - -#define GAME_VERSION "WTH?! 0.2.2 - by WilLoW" -#define ALPHA_WARNING 0 - -class GameStateMenu: public GameState, public JGuiListener - -{ -private: - JGuiController* mGuiController; - SimpleMenu* subMenuController; - JLBFont* mFont; - JQuad * mIcons[10]; - JTexture * mIconsTexture; - JTexture * bgTexture; - JQuad * mBg; - float mCreditsYPos; - int currentState; - JMusic * bgMusic; - int mVolume; - char nbcardsStr[400]; - - DIR *mDip; - struct dirent *mDit; - char mCurrentSetName[10]; - char mCurrentSetFileName[512]; - - int mReadConf; - - -public: - GameStateMenu(GameApp* parent): GameState(parent) - { - mGuiController = NULL; - subMenuController = NULL; - mIconsTexture = NULL; - bgMusic = NULL; - } - - virtual ~GameStateMenu() - { - - } - - - virtual void Create() - { - - mDip = NULL; - mReadConf = 0; - mCurrentSetName[0] = 0; - - - - - - mIconsTexture = JRenderer::GetInstance()->LoadTexture("graphics/menuicons.png", TEX_TYPE_USE_VRAM); - bgTexture = JRenderer::GetInstance()->LoadTexture("graphics/menutitle.png", TEX_TYPE_USE_VRAM); - mBg = NEW JQuad(bgTexture, 10, 0, 220, 80); // Create background quad for rendering. - mBg->SetHotSpot(105,32); - //load all the icon images - int n = 0; - for (int i=0;i<5;i++) - { - for (int j=0;j<2;j++) - { - mIcons[n] = NEW JQuad(mIconsTexture, 10 + i*32, j*32, 32, 32); - mIcons[n]->SetHotSpot(16,16); - n++; - } - } - - - - mFont = GameApp::CommonRes->GetJLBFont("graphics/f3"); - //mFont->SetBase(0); // using 2nd font - mGuiController = NEW JGuiController(100, this); - //mGuiController->SetShadingBackground(10, 45, 80, 100, ARGB(255,0,0,0)); - if (mGuiController) - { - mGuiController->Add(NEW MenuItem(1, mFont, "Play", 80, SCREEN_HEIGHT/2, mIcons[8], mIcons[9],"graphics/particle1.psi",GameApp::CommonRes->GetQuad("particles"), true)); - mGuiController->Add(NEW MenuItem(2, mFont, "Deck Editor", 160, SCREEN_HEIGHT/2, mIcons[2], mIcons[3],"graphics/particle2.psi",GameApp::CommonRes->GetQuad("particles"))); - mGuiController->Add(NEW MenuItem(3, mFont, "Shop", 240, SCREEN_HEIGHT/2, mIcons[0], mIcons[1],"graphics/particle3.psi",GameApp::CommonRes->GetQuad("particles"))); - mGuiController->Add(NEW MenuItem(4, mFont, "Options", 320, SCREEN_HEIGHT/2, mIcons[6], mIcons[7],"graphics/particle4.psi",GameApp::CommonRes->GetQuad("particles"))); - mGuiController->Add(NEW MenuItem(5, mFont, "Exit", 400, SCREEN_HEIGHT/2, mIcons[4], mIcons[5],"graphics/particle5.psi",GameApp::CommonRes->GetQuad("particles"))); - } - - - currentState = STATE_LOADING_CARDS; - - - - - - } - - - virtual void Destroy() - { - if (mGuiController) - delete mGuiController; - - if (subMenuController) - delete subMenuController; - - if (mIconsTexture) - delete mIconsTexture; - - for (int i = 0; i < 10 ; i++){ - delete mIcons[i]; - } - - if (mBg) delete mBg; - - SAFE_DELETE (bgMusic); - } - - - virtual void Start(){ - JRenderer::GetInstance()->ResetPrivateVRAM(); - JRenderer::GetInstance()->EnableVSync(true); - - if (GameApp::HasMusic && !bgMusic && GameOptions::GetInstance()->values[OPTIONS_MUSICVOLUME] > 0){ - bgMusic = JSoundSystem::GetInstance()->LoadMusic("sound/track0.mp3"); - } - - if (bgMusic){ - mVolume = 0; - JSoundSystem::GetInstance()->SetVolume(mVolume); - JSoundSystem::GetInstance()->PlayMusic(bgMusic, true); - } - - } - - - /* Retrieves the next set subfolder automatically - */ - int nextCardSet(){ - int found = 0; - if (!mDip){ - mDip = opendir("Res/sets/"); - } - - while (!found && (mDit = readdir(mDip))){ - sprintf(mCurrentSetFileName, "Res/sets/%s/_cards.dat", mDit->d_name); - std::ifstream file(mCurrentSetFileName); - if(file){ - sprintf(mCurrentSetName, "%s", mDit->d_name); - file.close(); - found = 1; - } - } - if (!mDit) { - closedir(mDip); - mDip = NULL; - } - return found; - } - - virtual void End() - { - //mEngine->EnableVSync(false); - - if (bgMusic) - { - JSoundSystem::GetInstance()->StopMusic(bgMusic); - } - JRenderer::GetInstance()->EnableVSync(false); - } - - - virtual void Update(float dt) - { - if (bgMusic && mVolume < 2*GameOptions::GetInstance()->values[OPTIONS_MUSICVOLUME]){ - mVolume++; - JSoundSystem::GetInstance()->SetVolume(mVolume/2); - } - - if (currentState == STATE_LOADING_CARDS){ - if (mReadConf){ - mParent->collection->load(mCurrentSetFileName, mCurrentSetName); - }else{ - mReadConf = 1; - } - if (!nextCardSet()){ - //How many cards total ? - sprintf(nbcardsStr, "Database: %i cards", mParent->collection->totalCards()); - //Check for first time comer - std::ifstream file("Res/player/collection.dat"); - if(file){ - file.close(); - currentState = STATE_WARNING; - }else{ - currentState = STATE_FIRST_TIME; - } - } - }else if (currentState == STATE_FIRST_TIME){ - //Give the player cards from the set for which we have the most variety - int setId = 0; - int maxcards = 0; - for (int i=0; i< MtgSets::SetsList->nb_items; i++){ - int value = mParent->collection->countBySet(i); - if (value > maxcards){ - maxcards = value; - setId = i; - } - } - createUsersFirstDeck(setId); - currentState = STATE_WARNING; - }else if (currentState == STATE_WARNING){ - if (!ALPHA_WARNING){ - currentState = STATE_MENU; - }else{ - if (mEngine->GetButtonClick(PSP_CTRL_CIRCLE)) currentState = STATE_MENU; - } - }else{ - if (currentState == STATE_MENU && mGuiController!=NULL) - mGuiController->Update(dt); - if (currentState == STATE_SUBMENU){ - 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(12, "2 Players"); - subMenuController->Add(13,"Demo"); - subMenuController->Add(14, "Cancel"); - #ifdef TESTSUITE - subMenuController->Add(666, "Test Suite"); - #endif - } - } - } - } - if (currentState == STATE_WARNING && !ALPHA_WARNING) currentState = STATE_MENU; - } - - void createUsersFirstDeck(int setId){ -#if defined (WIN32) || defined (LINUX) - char buf[4096]; - sprintf(buf, "setID: %i", setId); - OutputDebugString(buf); -#endif - MTGDeck *mCollection = NEW MTGDeck("Res/player/collection.dat", mParent->cache, mParent->collection); - //10 lands of each - if (!mCollection->addRandomCards(10, setId,RARITY_L,"Forest")){ - mCollection->addRandomCards(10, -1,RARITY_L,"Forest"); - } - if (!mCollection->addRandomCards(10, setId,RARITY_L,"Plains")){ - mCollection->addRandomCards(10, -1,RARITY_L,"Plains"); - } - if (!mCollection->addRandomCards(10, setId,RARITY_L,"Swamp")){ - mCollection->addRandomCards(10, -1,RARITY_L,"Swamp"); - } - if (!mCollection->addRandomCards(10, setId,RARITY_L,"Mountain")){ - mCollection->addRandomCards(10, -1,RARITY_L,"Mountain"); - } - if (!mCollection->addRandomCards(10, setId,RARITY_L,"Island")){ - mCollection->addRandomCards(10, -1,RARITY_L,"Island"); - } - - -#if defined (WIN32) || defined (LINUX) - OutputDebugString("1\n"); -#endif - - //Starter Deck - mCollection->addRandomCards(3, setId,RARITY_R,NULL); - mCollection->addRandomCards(9, setId,RARITY_U,NULL); - mCollection->addRandomCards(48, setId,RARITY_C,NULL); - -#if defined (WIN32) || defined (LINUX) - OutputDebugString("2\n"); -#endif - //Boosters - for (int i = 0; i< 2; i++){ - mCollection->addRandomCards(1, setId,RARITY_R); - mCollection->addRandomCards(3, setId,RARITY_U); - mCollection->addRandomCards(11, setId,RARITY_C); - } - mCollection->save(); - delete mCollection; - } - - virtual void Render() - { - - JRenderer * renderer = JRenderer::GetInstance(); - renderer->ClearScreen(ARGB(0,0,0,0)); - - if (currentState == STATE_LOADING_CARDS){ - char text[512]; - sprintf(text, "LOADING SET: %s", mCurrentSetName); - mFont->DrawString(text,SCREEN_WIDTH/2,SCREEN_HEIGHT/2,JGETEXT_CENTER); - }else{ - - - PIXEL_TYPE colors[] = - { - ARGB(255,17,17,17), - ARGB(255,17,17,17), - ARGB(255,62,62,62), - ARGB(255,62,62,62) - }; - - - - renderer->FillRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT,colors); - renderer->RenderQuad(mBg, SCREEN_WIDTH/2 , 50); - if (mGuiController!=NULL) - mGuiController->Render(); - - mFont->SetScale(0.7); - mFont->SetColor(ARGB(128,255,255,255)); - mFont->DrawString(GAME_VERSION, SCREEN_WIDTH-10,SCREEN_HEIGHT-15,JGETEXT_RIGHT); - mFont->DrawString(nbcardsStr,10, SCREEN_HEIGHT-15); - mFont->SetScale(1.f); - mFont->SetColor(ARGB(255,255,255,255)); - if (currentState == STATE_SUBMENU && subMenuController != NULL){ - subMenuController->Render(); - } - - if (currentState == STATE_WARNING){ - renderer->FillRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT,ARGB(128,0,0,0)); - - mFont->DrawString("IMPORTANT NOTE" ,SCREEN_WIDTH/2,10,JGETEXT_CENTER); - mFont->DrawString("This is an alpha version with lots of bugs.",SCREEN_WIDTH/2,35,JGETEXT_CENTER); - mFont->DrawString("It WILL crash your psp" ,SCREEN_WIDTH/2,50,JGETEXT_CENTER); - mFont->DrawString("If you use it anyway, your feedback is welcome" ,SCREEN_WIDTH/2,65,JGETEXT_CENTER); - - mFont->DrawString("This freeware game is NOT published or endorsed" ,SCREEN_WIDTH/2,110,JGETEXT_CENTER); - mFont->DrawString("by Wizard of the Coast, Inc." ,SCREEN_WIDTH/2,125,JGETEXT_CENTER); - mFont->DrawString("Infos & updates at http://wololo.net/wagic/" ,SCREEN_WIDTH/2,170,JGETEXT_CENTER); - mFont->DrawString("PRESS CIRCLE TO CONTINUE OR HOME TO QUIT" ,SCREEN_WIDTH/2,210,JGETEXT_CENTER); - - } - - - - } -} - - - virtual void ButtonPressed(int controllerId, int controlId) - { -#if defined (WIN32) || defined (LINUX) - char buf[4096]; - sprintf(buf, "cnotrollerId: %i", controllerId); - OutputDebugString(buf); -#endif - switch (controllerId){ - case 101: - createUsersFirstDeck(controlId); - currentState = STATE_MENU; - SAFE_DELETE(subMenuController); - break; - default: - switch (controlId) - { - case 1: - currentState = STATE_SUBMENU; - break; - case 2: - mParent->SetNextState(GAME_STATE_DECK_VIEWER); - break; - case 3: - mParent->SetNextState(GAME_STATE_SHOP); - break; - case 4: - mParent->SetNextState(GAME_STATE_OPTIONS); - break; - case 5: - mEngine->End(); - break; - case 11: - mParent->players[0] = PLAYER_TYPE_HUMAN; - mParent->players[1] = PLAYER_TYPE_CPU; - mParent->SetNextState(GAME_STATE_DUEL); - break; - case 12: - mParent->players[0] = PLAYER_TYPE_HUMAN; - mParent->players[1] = PLAYER_TYPE_HUMAN; - mParent->SetNextState(GAME_STATE_DUEL); - break; - case 13: - mParent->players[0] = PLAYER_TYPE_CPU; - mParent->players[1] = PLAYER_TYPE_CPU; - mParent->SetNextState(GAME_STATE_DUEL); - break; - case 14: - currentState = STATE_MENU; - delete subMenuController; - subMenuController = NULL; - break; -#ifdef TESTSUITE - case 666: - mParent->players[0] = PLAYER_TYPE_TESTSUITE; - mParent->players[1] = PLAYER_TYPE_TESTSUITE; - mParent->SetNextState(GAME_STATE_DUEL); - break; -#endif - } - break; - } - } - - -}; - - -#endif - +#ifndef _GAME_STATE_MENU_H_ +#define _GAME_STATE_MENU_H_ + +#include +#include + +#include "GameState.h" +#include "MenuItem.h" +#include "SimpleMenu.h" + +#include "../include/GameOptions.h" + + + +#define STATE_MENU 0 +#define STATE_SUBMENU 1 +#define STATE_LOADING_MENU 2 +#define STATE_LOADING_CARDS 3 +#define STATE_FIRST_TIME 4 +#define STATE_WARNING 5 + +#define GAME_VERSION "WTH?! 0.2.2 - by WilLoW" +#define ALPHA_WARNING 0 + +class GameStateMenu: public GameState, public JGuiListener + +{ + private: + JGuiController* mGuiController; + SimpleMenu* subMenuController; + JLBFont* mFont; + JQuad * mIcons[10]; + JTexture * mIconsTexture; + JTexture * bgTexture; + JQuad * mBg; + float mCreditsYPos; + int currentState; + JMusic * bgMusic; + int mVolume; + char nbcardsStr[400]; + + DIR *mDip; + struct dirent *mDit; + char mCurrentSetName[10]; + char mCurrentSetFileName[512]; + + int mReadConf; + + + public: + GameStateMenu(GameApp* parent): GameState(parent) + { + mGuiController = NULL; + subMenuController = NULL; + mIconsTexture = NULL; + bgMusic = NULL; + } + + virtual ~GameStateMenu() + { + + } + + + virtual void Create() + { + + mDip = NULL; + mReadConf = 0; + mCurrentSetName[0] = 0; + + + + + + mIconsTexture = JRenderer::GetInstance()->LoadTexture("graphics/menuicons.png", TEX_TYPE_USE_VRAM); + bgTexture = JRenderer::GetInstance()->LoadTexture("graphics/menutitle.png", TEX_TYPE_USE_VRAM); + mBg = NEW JQuad(bgTexture, 10, 0, 220, 80); // Create background quad for rendering. + mBg->SetHotSpot(105,32); + //load all the icon images + int n = 0; + for (int i=0;i<5;i++) + { + for (int j=0;j<2;j++) + { + mIcons[n] = NEW JQuad(mIconsTexture, 10 + i*32, j*32, 32, 32); + mIcons[n]->SetHotSpot(16,16); + n++; + } + } + + + + mFont = GameApp::CommonRes->GetJLBFont("graphics/f3"); + //mFont->SetBase(0); // using 2nd font + mGuiController = NEW JGuiController(100, this); + //mGuiController->SetShadingBackground(10, 45, 80, 100, ARGB(255,0,0,0)); + if (mGuiController) + { + mGuiController->Add(NEW MenuItem(1, mFont, "Play", 80, SCREEN_HEIGHT/2, mIcons[8], mIcons[9],"graphics/particle1.psi",GameApp::CommonRes->GetQuad("particles"), true)); + mGuiController->Add(NEW MenuItem(2, mFont, "Deck Editor", 160, SCREEN_HEIGHT/2, mIcons[2], mIcons[3],"graphics/particle2.psi",GameApp::CommonRes->GetQuad("particles"))); + mGuiController->Add(NEW MenuItem(3, mFont, "Shop", 240, SCREEN_HEIGHT/2, mIcons[0], mIcons[1],"graphics/particle3.psi",GameApp::CommonRes->GetQuad("particles"))); + mGuiController->Add(NEW MenuItem(4, mFont, "Options", 320, SCREEN_HEIGHT/2, mIcons[6], mIcons[7],"graphics/particle4.psi",GameApp::CommonRes->GetQuad("particles"))); + mGuiController->Add(NEW MenuItem(5, mFont, "Exit", 400, SCREEN_HEIGHT/2, mIcons[4], mIcons[5],"graphics/particle5.psi",GameApp::CommonRes->GetQuad("particles"))); + } + + + currentState = STATE_LOADING_CARDS; + + + + + + } + + + virtual void Destroy() + { + if (mGuiController) + delete mGuiController; + + if (subMenuController) + delete subMenuController; + + if (mIconsTexture) + delete mIconsTexture; + + for (int i = 0; i < 10 ; i++){ + delete mIcons[i]; + } + + if (mBg) delete mBg; + + SAFE_DELETE (bgMusic); + } + + + virtual void Start(){ + JRenderer::GetInstance()->ResetPrivateVRAM(); + JRenderer::GetInstance()->EnableVSync(true); + + if (GameApp::HasMusic && !bgMusic && GameOptions::GetInstance()->values[OPTIONS_MUSICVOLUME] > 0){ + bgMusic = JSoundSystem::GetInstance()->LoadMusic("sound/track0.mp3"); + } + + if (bgMusic){ + mVolume = 0; + JSoundSystem::GetInstance()->SetVolume(mVolume); + JSoundSystem::GetInstance()->PlayMusic(bgMusic, true); + } + + } + + + /* Retrieves the next set subfolder automatically + */ + int nextCardSet(){ + int found = 0; + if (!mDip){ + mDip = opendir("Res/sets/"); + } + + while (!found && (mDit = readdir(mDip))){ + sprintf(mCurrentSetFileName, "Res/sets/%s/_cards.dat", mDit->d_name); + std::ifstream file(mCurrentSetFileName); + if(file){ + sprintf(mCurrentSetName, "%s", mDit->d_name); + file.close(); + found = 1; + } + } + if (!mDit) { + closedir(mDip); + mDip = NULL; + } + return found; + } + + virtual void End() + { + //mEngine->EnableVSync(false); + + if (bgMusic) + { + JSoundSystem::GetInstance()->StopMusic(bgMusic); + } + JRenderer::GetInstance()->EnableVSync(false); + } + + + virtual void Update(float dt) + { + if (bgMusic && mVolume < 2*GameOptions::GetInstance()->values[OPTIONS_MUSICVOLUME]){ + mVolume++; + JSoundSystem::GetInstance()->SetVolume(mVolume/2); + } + + if (currentState == STATE_LOADING_CARDS){ + if (mReadConf){ + mParent->collection->load(mCurrentSetFileName, mCurrentSetName); + }else{ + mReadConf = 1; + } + if (!nextCardSet()){ + //How many cards total ? + sprintf(nbcardsStr, "Database: %i cards", mParent->collection->totalCards()); + //Check for first time comer + std::ifstream file("Res/player/collection.dat"); + if(file){ + file.close(); + currentState = STATE_WARNING; + }else{ + currentState = STATE_FIRST_TIME; + } + } + }else if (currentState == STATE_FIRST_TIME){ + //Give the player cards from the set for which we have the most variety + int setId = 0; + int maxcards = 0; + for (int i=0; i< MtgSets::SetsList->nb_items; i++){ + int value = mParent->collection->countBySet(i); + if (value > maxcards){ + maxcards = value; + setId = i; + } + } + createUsersFirstDeck(setId); + currentState = STATE_WARNING; + }else if (currentState == STATE_WARNING){ + if (!ALPHA_WARNING){ + currentState = STATE_MENU; + }else{ + if (mEngine->GetButtonClick(PSP_CTRL_CIRCLE)) currentState = STATE_MENU; + } + }else{ + if (currentState == STATE_MENU && mGuiController!=NULL) + mGuiController->Update(dt); + if (currentState == STATE_SUBMENU){ + 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(12, "2 Players"); + subMenuController->Add(13,"Demo"); + subMenuController->Add(14, "Cancel"); +#ifdef TESTSUITE + subMenuController->Add(666, "Test Suite"); +#endif + } + } + } + } + if (currentState == STATE_WARNING && !ALPHA_WARNING) currentState = STATE_MENU; + } + + void createUsersFirstDeck(int setId){ +#if defined (WIN32) || defined (LINUX) + char buf[4096]; + sprintf(buf, "setID: %i", setId); + OutputDebugString(buf); +#endif + MTGDeck *mCollection = NEW MTGDeck("Res/player/collection.dat", mParent->cache, mParent->collection); + //10 lands of each + if (!mCollection->addRandomCards(10, setId,RARITY_L,"Forest")){ + mCollection->addRandomCards(10, -1,RARITY_L,"Forest"); + } + if (!mCollection->addRandomCards(10, setId,RARITY_L,"Plains")){ + mCollection->addRandomCards(10, -1,RARITY_L,"Plains"); + } + if (!mCollection->addRandomCards(10, setId,RARITY_L,"Swamp")){ + mCollection->addRandomCards(10, -1,RARITY_L,"Swamp"); + } + if (!mCollection->addRandomCards(10, setId,RARITY_L,"Mountain")){ + mCollection->addRandomCards(10, -1,RARITY_L,"Mountain"); + } + if (!mCollection->addRandomCards(10, setId,RARITY_L,"Island")){ + mCollection->addRandomCards(10, -1,RARITY_L,"Island"); + } + + +#if defined (WIN32) || defined (LINUX) + OutputDebugString("1\n"); +#endif + + //Starter Deck + mCollection->addRandomCards(3, setId,RARITY_R,NULL); + mCollection->addRandomCards(9, setId,RARITY_U,NULL); + mCollection->addRandomCards(48, setId,RARITY_C,NULL); + +#if defined (WIN32) || defined (LINUX) + OutputDebugString("2\n"); +#endif + //Boosters + for (int i = 0; i< 2; i++){ + mCollection->addRandomCards(1, setId,RARITY_R); + mCollection->addRandomCards(3, setId,RARITY_U); + mCollection->addRandomCards(11, setId,RARITY_C); + } + mCollection->save(); + delete mCollection; + } + + virtual void Render() + { + + JRenderer * renderer = JRenderer::GetInstance(); + renderer->ClearScreen(ARGB(0,0,0,0)); + + if (currentState == STATE_LOADING_CARDS){ + char text[512]; + sprintf(text, "LOADING SET: %s", mCurrentSetName); + mFont->DrawString(text,SCREEN_WIDTH/2,SCREEN_HEIGHT/2,JGETEXT_CENTER); + }else{ + + + PIXEL_TYPE colors[] = + { + ARGB(255,17,17,17), + ARGB(255,17,17,17), + ARGB(255,62,62,62), + ARGB(255,62,62,62) + }; + + + + renderer->FillRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT,colors); + renderer->RenderQuad(mBg, SCREEN_WIDTH/2 , 50); + if (mGuiController!=NULL) + mGuiController->Render(); + + mFont->SetScale(0.7); + mFont->SetColor(ARGB(128,255,255,255)); + mFont->DrawString(GAME_VERSION, SCREEN_WIDTH-10,SCREEN_HEIGHT-15,JGETEXT_RIGHT); + mFont->DrawString(nbcardsStr,10, SCREEN_HEIGHT-15); + mFont->SetScale(1.f); + mFont->SetColor(ARGB(255,255,255,255)); + if (currentState == STATE_SUBMENU && subMenuController != NULL){ + subMenuController->Render(); + } + + if (currentState == STATE_WARNING){ + renderer->FillRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT,ARGB(128,0,0,0)); + + mFont->DrawString("IMPORTANT NOTE" ,SCREEN_WIDTH/2,10,JGETEXT_CENTER); + mFont->DrawString("This is an alpha version with lots of bugs.",SCREEN_WIDTH/2,35,JGETEXT_CENTER); + mFont->DrawString("It WILL crash your psp" ,SCREEN_WIDTH/2,50,JGETEXT_CENTER); + mFont->DrawString("If you use it anyway, your feedback is welcome" ,SCREEN_WIDTH/2,65,JGETEXT_CENTER); + + mFont->DrawString("This freeware game is NOT published or endorsed" ,SCREEN_WIDTH/2,110,JGETEXT_CENTER); + mFont->DrawString("by Wizard of the Coast, Inc." ,SCREEN_WIDTH/2,125,JGETEXT_CENTER); + mFont->DrawString("Infos & updates at http://wololo.net/wagic/" ,SCREEN_WIDTH/2,170,JGETEXT_CENTER); + mFont->DrawString("PRESS CIRCLE TO CONTINUE OR HOME TO QUIT" ,SCREEN_WIDTH/2,210,JGETEXT_CENTER); + + } + + + + } + } + + + virtual void ButtonPressed(int controllerId, int controlId) + { +#if defined (WIN32) || defined (LINUX) + char buf[4096]; + sprintf(buf, "cnotrollerId: %i", controllerId); + OutputDebugString(buf); +#endif + switch (controllerId){ + case 101: + createUsersFirstDeck(controlId); + currentState = STATE_MENU; + SAFE_DELETE(subMenuController); + break; + default: + switch (controlId) + { + case 1: + currentState = STATE_SUBMENU; + break; + case 2: + mParent->SetNextState(GAME_STATE_DECK_VIEWER); + break; + case 3: + mParent->SetNextState(GAME_STATE_SHOP); + break; + case 4: + mParent->SetNextState(GAME_STATE_OPTIONS); + break; + case 5: + mEngine->End(); + break; + case 11: + mParent->players[0] = PLAYER_TYPE_HUMAN; + mParent->players[1] = PLAYER_TYPE_CPU; + mParent->SetNextState(GAME_STATE_DUEL); + break; + case 12: + mParent->players[0] = PLAYER_TYPE_HUMAN; + mParent->players[1] = PLAYER_TYPE_HUMAN; + mParent->SetNextState(GAME_STATE_DUEL); + break; + case 13: + mParent->players[0] = PLAYER_TYPE_CPU; + mParent->players[1] = PLAYER_TYPE_CPU; + mParent->SetNextState(GAME_STATE_DUEL); + break; + case 14: + currentState = STATE_MENU; + delete subMenuController; + subMenuController = NULL; + break; +#ifdef TESTSUITE + case 666: + mParent->players[0] = PLAYER_TYPE_TESTSUITE; + mParent->players[1] = PLAYER_TYPE_TESTSUITE; + mParent->SetNextState(GAME_STATE_DUEL); + break; +#endif + } + break; + } + } + + +}; + + +#endif + diff --git a/projects/mtg/include/GameStateOptions.h b/projects/mtg/include/GameStateOptions.h index c54d68ea6..e80ef3e07 100644 --- a/projects/mtg/include/GameStateOptions.h +++ b/projects/mtg/include/GameStateOptions.h @@ -1,34 +1,34 @@ -#ifndef _GAME_STATE_OPTIONS_H_ -#define _GAME_STATE_OPTIONS_H_ - -#include -#include "../include/GameState.h" - -#define SHOW_OPTIONS 1 -#define SHOW_OPTIONS_MENU 2 - -class GameApp; -class OptionsList; -class SimpleMenu; - -class GameStateOptions: public GameState, public JGuiListener -{ - -public: - SimpleMenu * optionsMenu; - int mState; - OptionsList * optionsList; - GameStateOptions(GameApp* parent); - virtual ~GameStateOptions(); - - virtual void Start(); - virtual void End(); - virtual void Update(float dt); - virtual void Render(); - void ButtonPressed(int controllerId, int ControlId); - -}; - - -#endif - +#ifndef _GAME_STATE_OPTIONS_H_ +#define _GAME_STATE_OPTIONS_H_ + +#include +#include "../include/GameState.h" + +#define SHOW_OPTIONS 1 +#define SHOW_OPTIONS_MENU 2 + +class GameApp; +class OptionsList; +class SimpleMenu; + +class GameStateOptions: public GameState, public JGuiListener +{ + + public: + SimpleMenu * optionsMenu; + int mState; + OptionsList * optionsList; + GameStateOptions(GameApp* parent); + virtual ~GameStateOptions(); + + virtual void Start(); + virtual void End(); + virtual void Update(float dt); + virtual void Render(); + void ButtonPressed(int controllerId, int ControlId); + +}; + + +#endif + diff --git a/projects/mtg/include/GameStateShop.h b/projects/mtg/include/GameStateShop.h index 88b1e7115..de6721f4f 100644 --- a/projects/mtg/include/GameStateShop.h +++ b/projects/mtg/include/GameStateShop.h @@ -1,46 +1,46 @@ -#ifndef _GAME_STATE_SHOP_H_ -#define _GAME_STATE_SHOP_H_ - -#include -#include "../include/GameState.h" -#include "../include/SimpleMenu.h" -#include "../include/ShopItem.h" - - -#define STATE_BUY 1 -#define STATE_SELL 2 -#define STAGE_SHOP_MENU 3 -#define STAGE_SHOP_SHOP 4 - -class GameStateShop: public GameState, public JGuiListener -{ -private: - - ShopItems * shop; - JLBFont * mFont; - JQuad * mBg; - JTexture * bgTexture; - JQuad * mBack; - JTexture * backTexture; - SimpleMenu * menu; - int mStage; - char starterBuffer[128], boosterBuffer[128]; - int setId; - -public: - GameStateShop(GameApp* parent); - virtual ~GameStateShop(); - - virtual void Start(); - virtual void End(); - virtual void Create(); - virtual void Destroy(); - virtual void Update(float dt); - virtual void Render(); - virtual void ButtonPressed(int controllerId, int controlId); - -}; - - -#endif - +#ifndef _GAME_STATE_SHOP_H_ +#define _GAME_STATE_SHOP_H_ + +#include +#include "../include/GameState.h" +#include "../include/SimpleMenu.h" +#include "../include/ShopItem.h" + + +#define STATE_BUY 1 +#define STATE_SELL 2 +#define STAGE_SHOP_MENU 3 +#define STAGE_SHOP_SHOP 4 + +class GameStateShop: public GameState, public JGuiListener +{ + private: + + ShopItems * shop; + JLBFont * mFont; + JQuad * mBg; + JTexture * bgTexture; + JQuad * mBack; + JTexture * backTexture; + SimpleMenu * menu; + int mStage; + char starterBuffer[128], boosterBuffer[128]; + int setId; + + public: + GameStateShop(GameApp* parent); + virtual ~GameStateShop(); + + virtual void Start(); + virtual void End(); + virtual void Create(); + virtual void Destroy(); + virtual void Update(float dt); + virtual void Render(); + virtual void ButtonPressed(int controllerId, int controlId); + +}; + + +#endif + diff --git a/projects/mtg/include/GuiCardsController.h b/projects/mtg/include/GuiCardsController.h index 10318f87b..abdea55df 100644 --- a/projects/mtg/include/GuiCardsController.h +++ b/projects/mtg/include/GuiCardsController.h @@ -5,8 +5,8 @@ #include "PlayGuiObjectController.h" class GuiCardsController : public PlayGuiObjectController{ -public: - GuiCardsController(int id, GameObserver* _game):PlayGuiObjectController(id, _game){}; + public: + GuiCardsController(int id, GameObserver* _game):PlayGuiObjectController(id, _game){}; }; diff --git a/projects/mtg/include/GuiLayers.h b/projects/mtg/include/GuiLayers.h index 07b87e732..03c0bfbc9 100644 --- a/projects/mtg/include/GuiLayers.h +++ b/projects/mtg/include/GuiLayers.h @@ -20,9 +20,9 @@ class GuiLayer: public JGuiController{ GameObserver * game; public: virtual void resetObjects(); - int hasFocus; - int getMaxId(); - void RenderMessageBackground(float x0, float y0, float width, int height); + int hasFocus; + int getMaxId(); + void RenderMessageBackground(float x0, float y0, float width, int height); void RenderMessageBackground(float y0, int height); GuiLayer(int id, GameObserver* _game); virtual int isModal(); @@ -34,10 +34,10 @@ class GuiLayer: public JGuiController{ int getIndexOf(JGuiObject * object); JGuiObject * getByIndex (int index); virtual void Render(){JGuiController::Render();}; - int empty(){ - if (mCount) return 0; - return 1; - }; + int empty(){ + if (mCount) return 0; + return 1; + }; }; class GuiLayers{ diff --git a/projects/mtg/include/Logger.h b/projects/mtg/include/Logger.h index 916d99384..ef3d8eb4f 100644 --- a/projects/mtg/include/Logger.h +++ b/projects/mtg/include/Logger.h @@ -1,20 +1,20 @@ -#ifndef _LOGGER_H -#define _LOGGER_H_ - - - - -#ifdef DOLOG -#define LOG(x) Logger::Log(x); -#else -#define LOG(x) -#endif - -#define LOG_FILE "Res/debug.txt" - -class Logger{ -public: - static void Log(char * text); -}; - -#endif +#ifndef _LOGGER_H +#define _LOGGER_H_ + + + + +#ifdef DOLOG +#define LOG(x) Logger::Log(x); +#else +#define LOG(x) +#endif + +#define LOG_FILE "Res/debug.txt" + +class Logger{ + public: + static void Log(char * text); +}; + +#endif diff --git a/projects/mtg/include/MTGAbility.h b/projects/mtg/include/MTGAbility.h index 779bdfc87..d0d14a7cd 100644 --- a/projects/mtg/include/MTGAbility.h +++ b/projects/mtg/include/MTGAbility.h @@ -1,118 +1,118 @@ -#ifndef _MTGABILITY_H_ -#define _MTGABILITY_H_ - - - -class MTGCardInstance; -class GameObserver; -class Spell; -class Damageable; -class PlayGuiObject; -class TargetChooser; -class ManaCost; -class MTGGameZone; -class Player; - -#include "ActionElement.h" -#include -#include -using std::string; -using std::map; - - -#define BAKA_EFFECT_GOOD 10 -#define BAKA_EFFECT_BAD 11 - -class AbilityFactory{ -private: - int destroyAllFromTypeInPlay(const char * type, MTGCardInstance * source, int bury = 0); - int destroyAllFromColorInPlay(int color, MTGCardInstance * source, int bury = 0); - int putInPlayFromZone(MTGCardInstance * card, MTGGameZone * zone, Player * p); - public: - int magicText(int id, Spell * spell, MTGCardInstance * card = NULL); - void addAbilities(int _id, Spell * spell); -}; - -class MTGAbility: public ActionElement{ - protected: - char menuText[25]; - Damageable * target; - GameObserver * game; - public: - MTGCardInstance * source; - MTGAbility(int id, MTGCardInstance * card); - MTGAbility(int id, MTGCardInstance * _source, Damageable * _target); - virtual int testDestroy(); - virtual ~MTGAbility(); - virtual void Render(){}; - virtual int isReactingToClick(MTGCardInstance * card){return 0;}; - virtual int reactToClick(MTGCardInstance * card){return 0;}; - virtual void Update(float dt){}; - virtual int fireAbility(); - virtual int resolve(){return 0;}; - - -}; - - -class TriggeredAbility:public MTGAbility{ - public: - TriggeredAbility(int id, MTGCardInstance * card); - TriggeredAbility(int id, MTGCardInstance * _source, Damageable * _target); - virtual void Update(float dt); - virtual void Render(){}; - virtual int trigger()=0; - virtual int resolve() = 0; -}; - - -class ActivatedAbility:public MTGAbility{ -public: - ManaCost * cost; - int playerturnonly; - int needsTapping; - ActivatedAbility(int id, MTGCardInstance * card,ManaCost * _cost = NULL, int _playerturnonly = 0,int tap = 1); - virtual int reactToClick(MTGCardInstance * card); - virtual int isReactingToClick(MTGCardInstance * card); - virtual int reactToTargetClick(Targetable * object); - virtual int resolve() = 0; - virtual ~ActivatedAbility(); -}; - -class TargetAbility:public ActivatedAbility{ -public: - TargetAbility(int id, MTGCardInstance * card, TargetChooser * _tc,ManaCost * _cost = NULL, int _playerturnonly = 0,int tap = 1); - TargetAbility(int id, MTGCardInstance * card,ManaCost * _cost = NULL, int _playerturnonly = 0,int tap = 1); - virtual void Update(float dt); - virtual int reactToClick(MTGCardInstance * card); - virtual int reactToTargetClick(Targetable * object); - virtual void Render(); -}; - -class InstantAbility:public MTGAbility{ -public: - int init; - virtual void Update(float dt); - virtual int testDestroy(); - InstantAbility(int _id, MTGCardInstance * source); - InstantAbility(int _id, MTGCardInstance * source,Damageable * _target); - virtual int resolve(){return 0;}; -}; - -/* State based effects. This class works ONLY for InPlay and needs to be extended for other areas of the game !!! */ -class ListMaintainerAbility:public MTGAbility{ -public: - map cards; - ListMaintainerAbility(int _id):MTGAbility(_id,NULL){}; - ListMaintainerAbility(int _id, MTGCardInstance *_source):MTGAbility(_id, _source){}; - ListMaintainerAbility(int _id, MTGCardInstance *_source,Damageable * _target):MTGAbility(_id, _source, _target){}; - virtual void Update(float dt); - virtual int canBeInList(MTGCardInstance * card) = 0; - virtual int added(MTGCardInstance * card) = 0; - virtual int removed(MTGCardInstance * card) = 0; - virtual int destroy(); -}; - -#include "MTGCardInstance.h" - -#endif +#ifndef _MTGABILITY_H_ +#define _MTGABILITY_H_ + + + +class MTGCardInstance; +class GameObserver; +class Spell; +class Damageable; +class PlayGuiObject; +class TargetChooser; +class ManaCost; +class MTGGameZone; +class Player; + +#include "ActionElement.h" +#include +#include +using std::string; +using std::map; + + +#define BAKA_EFFECT_GOOD 10 +#define BAKA_EFFECT_BAD 11 + +class AbilityFactory{ + private: + int destroyAllFromTypeInPlay(const char * type, MTGCardInstance * source, int bury = 0); + int destroyAllFromColorInPlay(int color, MTGCardInstance * source, int bury = 0); + int putInPlayFromZone(MTGCardInstance * card, MTGGameZone * zone, Player * p); + public: + int magicText(int id, Spell * spell, MTGCardInstance * card = NULL); + void addAbilities(int _id, Spell * spell); +}; + +class MTGAbility: public ActionElement{ + protected: + char menuText[25]; + Damageable * target; + GameObserver * game; + public: + MTGCardInstance * source; + MTGAbility(int id, MTGCardInstance * card); + MTGAbility(int id, MTGCardInstance * _source, Damageable * _target); + virtual int testDestroy(); + virtual ~MTGAbility(); + virtual void Render(){}; + virtual int isReactingToClick(MTGCardInstance * card){return 0;}; + virtual int reactToClick(MTGCardInstance * card){return 0;}; + virtual void Update(float dt){}; + virtual int fireAbility(); + virtual int resolve(){return 0;}; + + +}; + + +class TriggeredAbility:public MTGAbility{ + public: + TriggeredAbility(int id, MTGCardInstance * card); + TriggeredAbility(int id, MTGCardInstance * _source, Damageable * _target); + virtual void Update(float dt); + virtual void Render(){}; + virtual int trigger()=0; + virtual int resolve() = 0; +}; + + +class ActivatedAbility:public MTGAbility{ + public: + ManaCost * cost; + int playerturnonly; + int needsTapping; + ActivatedAbility(int id, MTGCardInstance * card,ManaCost * _cost = NULL, int _playerturnonly = 0,int tap = 1); + virtual int reactToClick(MTGCardInstance * card); + virtual int isReactingToClick(MTGCardInstance * card); + virtual int reactToTargetClick(Targetable * object); + virtual int resolve() = 0; + virtual ~ActivatedAbility(); +}; + +class TargetAbility:public ActivatedAbility{ + public: + TargetAbility(int id, MTGCardInstance * card, TargetChooser * _tc,ManaCost * _cost = NULL, int _playerturnonly = 0,int tap = 1); + TargetAbility(int id, MTGCardInstance * card,ManaCost * _cost = NULL, int _playerturnonly = 0,int tap = 1); + virtual void Update(float dt); + virtual int reactToClick(MTGCardInstance * card); + virtual int reactToTargetClick(Targetable * object); + virtual void Render(); +}; + +class InstantAbility:public MTGAbility{ + public: + int init; + virtual void Update(float dt); + virtual int testDestroy(); + InstantAbility(int _id, MTGCardInstance * source); + InstantAbility(int _id, MTGCardInstance * source,Damageable * _target); + virtual int resolve(){return 0;}; +}; + +/* State based effects. This class works ONLY for InPlay and needs to be extended for other areas of the game !!! */ +class ListMaintainerAbility:public MTGAbility{ + public: + map cards; + ListMaintainerAbility(int _id):MTGAbility(_id,NULL){}; + ListMaintainerAbility(int _id, MTGCardInstance *_source):MTGAbility(_id, _source){}; + ListMaintainerAbility(int _id, MTGCardInstance *_source,Damageable * _target):MTGAbility(_id, _source, _target){}; + virtual void Update(float dt); + virtual int canBeInList(MTGCardInstance * card) = 0; + virtual int added(MTGCardInstance * card) = 0; + virtual int removed(MTGCardInstance * card) = 0; + virtual int destroy(); +}; + +#include "MTGCardInstance.h" + +#endif diff --git a/projects/mtg/include/MTGCard.h b/projects/mtg/include/MTGCard.h index cd60d21a9..fed66f1e7 100644 --- a/projects/mtg/include/MTGCard.h +++ b/projects/mtg/include/MTGCard.h @@ -1,119 +1,119 @@ -#ifndef _MTGCARD_H_ -#define _MTGCARD_H_ - -#define MTGCARD_NAME_SIZE 30 -#define MTGCARD_TEXT_SIZE 300 - -#define MTG_IMAGE_WIDTH 200 -#define MTG_IMAGE_HEIGHT 285 - - -#define MAX_TYPES_PER_CARD 10 - - - - -#include "ManaCost.h" - - -class TexturesCache; - - -#include -#include -using namespace std; - -class MTGCard { - protected: - - - - int mtgid; - TexturesCache * mCache; - ManaCost manaCost; - - - char rarity; - - char image_name[MTGCARD_NAME_SIZE]; - - int init(); - - public: - string text; - string name; - int colors[MTG_NB_COLORS]; - int basicAbilities[NB_BASIC_ABILITIES]; - vector formattedText; - string magicText; - int alias; - string spellTargetType; - int formattedTextInit; - int power; - int toughness; - int setId; - static const char * const Colors_To_Text[]; - int nb_types; - int types[MAX_TYPES_PER_CARD]; - MTGCard(); - MTGCard(TexturesCache * cache, int set_id); - MTGCard(MTGCard * source); - JQuad * getQuad(TexturesCache * cache); - JQuad * getQuad(int type=1); - JQuad * getThumb(); - - void setColor(int _color, int removeAllOthers = 0); - int getColor(); - int hasColor(int _color); - const char * colorToString(); - - void setMTGId(int id); - int getMTGId(); - int getId(); - - int has(int ability); - - char getRarity(); - void setRarity(char _rarity); - - const char * getSetName(); - - //void setImageName( char * value); - char * getImageName (); - - void setText( string value); - const char * getText(); - - void addMagicText(string value); - - void setName( string value); - const char * getName(); - - void addType(char * type_text); - void addType(int id); - void setType(const char * type_text); - void setSubtype( string value); - int removeType(string value, int removeAll = 0); - int removeType(int value, int removeAll = 0); - int hasSubtype(int _subtype); - int hasSubtype(const char * _subtype); - int hasSubtype(string _subtype); - int hasType(int _type); - int hasType(const char * type); - - void setManaCost(string value); - ManaCost * getManaCost(); - int isACreature(); - - void setPower(int _power); - int getPower(); - void setToughness(int _toughness); - int getToughness(); - - -}; - - - - -#endif +#ifndef _MTGCARD_H_ +#define _MTGCARD_H_ + +#define MTGCARD_NAME_SIZE 30 +#define MTGCARD_TEXT_SIZE 300 + +#define MTG_IMAGE_WIDTH 200 +#define MTG_IMAGE_HEIGHT 285 + + +#define MAX_TYPES_PER_CARD 10 + + + + +#include "ManaCost.h" + + +class TexturesCache; + + +#include +#include +using namespace std; + +class MTGCard { + protected: + + + + int mtgid; + TexturesCache * mCache; + ManaCost manaCost; + + + char rarity; + + char image_name[MTGCARD_NAME_SIZE]; + + int init(); + + public: + string text; + string name; + int colors[MTG_NB_COLORS]; + int basicAbilities[NB_BASIC_ABILITIES]; + vector formattedText; + string magicText; + int alias; + string spellTargetType; + int formattedTextInit; + int power; + int toughness; + int setId; + static const char * const Colors_To_Text[]; + int nb_types; + int types[MAX_TYPES_PER_CARD]; + MTGCard(); + MTGCard(TexturesCache * cache, int set_id); + MTGCard(MTGCard * source); + JQuad * getQuad(TexturesCache * cache); + JQuad * getQuad(int type=1); + JQuad * getThumb(); + + void setColor(int _color, int removeAllOthers = 0); + int getColor(); + int hasColor(int _color); + const char * colorToString(); + + void setMTGId(int id); + int getMTGId(); + int getId(); + + int has(int ability); + + char getRarity(); + void setRarity(char _rarity); + + const char * getSetName(); + + //void setImageName( char * value); + char * getImageName (); + + void setText( string value); + const char * getText(); + + void addMagicText(string value); + + void setName( string value); + const char * getName(); + + void addType(char * type_text); + void addType(int id); + void setType(const char * type_text); + void setSubtype( string value); + int removeType(string value, int removeAll = 0); + int removeType(int value, int removeAll = 0); + int hasSubtype(int _subtype); + int hasSubtype(const char * _subtype); + int hasSubtype(string _subtype); + int hasType(int _type); + int hasType(const char * type); + + void setManaCost(string value); + ManaCost * getManaCost(); + int isACreature(); + + void setPower(int _power); + int getPower(); + void setToughness(int _toughness); + int getToughness(); + + +}; + + + + +#endif diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index ffdf694e2..f00d77820 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -25,68 +25,68 @@ class Counters; class MTGCardInstance: public MTGCard, public Damageable, public Targetable { protected: - int untapping; + int untapping; int nb_damages; - - int lifeOrig; - Blockers * blockers; + + int lifeOrig; + Blockers * blockers; MTGPlayerCards * belongs_to; MTGAbility * UntapBlockers[10]; -void unband(); - MTGCardInstance * getNextPartner(); - void initMTGCI(); + void unband(); + MTGCardInstance * getNextPartner(); + void initMTGCI(); public: - MTGGameZone * getCurrentZone(); - int doDamageTest; - int summoningSickness; - // The recommended method to test for summoning Sickness ! - int hasSummoningSickness(); - int changeController(Player * newcontroller); - MTGCardInstance * defenser; - float changedZoneRecently; - Player * owner; - Counters * counters; - int typeAsTarget(){return TARGET_CARD;} - int attacker; - MTGCardInstance * banding; // If belongs to a band when attacking + MTGGameZone * getCurrentZone(); + int doDamageTest; + int summoningSickness; + // The recommended method to test for summoning Sickness ! + int hasSummoningSickness(); + int changeController(Player * newcontroller); + MTGCardInstance * defenser; + float changedZoneRecently; + Player * owner; + Counters * counters; + int typeAsTarget(){return TARGET_CARD;} + int attacker; + MTGCardInstance * banding; // If belongs to a band when attacking MTGCardInstance * target; - int tapped; - void addType(int type); - int canBlock(); - int canBlock(MTGCardInstance * opponent); - int canAttack(); + int tapped; + void addType(int type); + int canBlock(); + int canBlock(MTGCardInstance * opponent); + int canAttack(); int afterDamage(); - void setUntapping(); - int isUntapping(); - int has(int ability); - int cleanup(); - int reset(); - int isAttacker(); - MTGCardInstance * isDefenser(); - int toggleDefenser(MTGCardInstance * opponent); - int toggleAttacker(); + void setUntapping(); + int isUntapping(); + int has(int ability); + int cleanup(); + int reset(); + int isAttacker(); + MTGCardInstance * isDefenser(); + int toggleDefenser(MTGCardInstance * opponent); + int toggleAttacker(); MTGCard * model; - MTGCardInstance(); + MTGCardInstance(); MTGCardInstance(MTGCard * card, MTGPlayerCards * _belongs_to); - Blockers * getBlockers(); + Blockers * getBlockers(); void regenerate(); - Player * controller(); - JQuad * getIcon(); - int initAttackersDefensers(); - MTGCardInstance * getNextOpponent(MTGCardInstance * previous=NULL); - int nbOpponents(); - ~MTGCardInstance(); + Player * controller(); + JQuad * getIcon(); + int initAttackersDefensers(); + MTGCardInstance * getNextOpponent(MTGCardInstance * previous=NULL); + int nbOpponents(); + ~MTGCardInstance(); - int addToToughness(int value); - int setToughness(int value); + int addToToughness(int value); + int setToughness(int value); - CardDescriptor * protections[10]; - int nbprotections; - int addProtection(CardDescriptor * cd); - int removeProtection(CardDescriptor *cd, int erase = 0); - int protectedAgainst(MTGCardInstance * card); + CardDescriptor * protections[10]; + int nbprotections; + int addProtection(CardDescriptor * cd); + int removeProtection(CardDescriptor *cd, int erase = 0); + int protectedAgainst(MTGCardInstance * card); // in game int isTapped(); diff --git a/projects/mtg/include/MTGDeck.h b/projects/mtg/include/MTGDeck.h index 0d6fafa7d..738f6f2b1 100644 --- a/projects/mtg/include/MTGDeck.h +++ b/projects/mtg/include/MTGDeck.h @@ -1,91 +1,91 @@ -#ifndef _MTGDECK_H_ -#define _MTGDECK_H_ - -#define MTG_ERROR -1 - -#include "../include/MTGDefinitions.h" - - - - - - -#include "../include/GameApp.h" -#include "../include/TexturesCache.h" -#include -using std::string; - -class GameApp; -class MTGCard; - - -#define MAX_SETS 30 - - - -class MtgSets{ -protected: -public: - int nb_items; - string values[MAX_SETS]; - -public: - static MtgSets * SetsList; - MtgSets(); - int Add(const char * subtype); - -}; - - -class MTGAllCards { - protected: - int conf_read_mode; - int conf_fd; - char * conf_buffer; - int read_cursor; - int colorsCount[MTG_NB_COLORS]; - int total_cards; - GameApp * parent; - void init(); - void initCounters(); - public: - - TexturesCache * mCache; - MTGCard * _(int i); - MTGCard * collection[TOTAL_NUMBER_OF_CARDS]; - MTGAllCards(); - ~MTGAllCards(); - MTGAllCards(TexturesCache * cache); - void destroyAllCards(); - MTGAllCards(const char * config_file, const char * set_name); - MTGAllCards(const char * config_file, const char * set_name, TexturesCache * cache); - MTGCard * getCardById(int id); - int load(const char * config_file, const char * setName, int autoload = 1); - int countByType(const char * _type); - int countByColor(int color); - int countBySet(int setId); - int readConfLine(int set_id); - int totalCards(); - int randomCardId(); - private: - int processConfLine(char* file, MTGCard* card); -}; - - -class MTGDeck:public MTGAllCards{ -protected: - string filename; - MTGAllCards * allcards; -public: - MTGDeck(const char * config_file, TexturesCache * cache, MTGAllCards * _allcards); - int addRandomCards(int howmany, int setId = -1, int rarity = -1, const char * subtype = NULL); - int add(int cardid); - int remove(int cardid); - int removeAll(); - int add(MTGCard * card); - int remove(MTGCard * card); - int save(); -}; - - -#endif +#ifndef _MTGDECK_H_ +#define _MTGDECK_H_ + +#define MTG_ERROR -1 + +#include "../include/MTGDefinitions.h" + + + + + + +#include "../include/GameApp.h" +#include "../include/TexturesCache.h" +#include +using std::string; + +class GameApp; +class MTGCard; + + +#define MAX_SETS 30 + + + +class MtgSets{ + protected: + public: + int nb_items; + string values[MAX_SETS]; + + public: + static MtgSets * SetsList; + MtgSets(); + int Add(const char * subtype); + +}; + + +class MTGAllCards { + protected: + int conf_read_mode; + int conf_fd; + char * conf_buffer; + int read_cursor; + int colorsCount[MTG_NB_COLORS]; + int total_cards; + GameApp * parent; + void init(); + void initCounters(); + public: + + TexturesCache * mCache; + MTGCard * _(int i); + MTGCard * collection[TOTAL_NUMBER_OF_CARDS]; + MTGAllCards(); + ~MTGAllCards(); + MTGAllCards(TexturesCache * cache); + void destroyAllCards(); + MTGAllCards(const char * config_file, const char * set_name); + MTGAllCards(const char * config_file, const char * set_name, TexturesCache * cache); + MTGCard * getCardById(int id); + int load(const char * config_file, const char * setName, int autoload = 1); + int countByType(const char * _type); + int countByColor(int color); + int countBySet(int setId); + int readConfLine(int set_id); + int totalCards(); + int randomCardId(); + private: + int processConfLine(char* file, MTGCard* card); +}; + + +class MTGDeck:public MTGAllCards{ + protected: + string filename; + MTGAllCards * allcards; + public: + MTGDeck(const char * config_file, TexturesCache * cache, MTGAllCards * _allcards); + int addRandomCards(int howmany, int setId = -1, int rarity = -1, const char * subtype = NULL); + int add(int cardid); + int remove(int cardid); + int removeAll(); + int add(MTGCard * card); + int remove(MTGCard * card); + int save(); +}; + + +#endif diff --git a/projects/mtg/include/MTGDefinitions.h b/projects/mtg/include/MTGDefinitions.h index 551b26e41..dd2078aa5 100644 --- a/projects/mtg/include/MTGDefinitions.h +++ b/projects/mtg/include/MTGDefinitions.h @@ -1,176 +1,176 @@ -#ifndef _MTGDEFINITION_H_ -#define _MTGDEFINITION_H_ - - -#define TOTAL_NUMBER_OF_CARDS 4000 - -#define MTG_NB_COLORS 7 - -#define MTG_COLOR_ARTIFACT 0 -#define MTG_COLOR_GREEN 1 -#define MTG_COLOR_BLUE 2 -#define MTG_COLOR_RED 3 -#define MTG_COLOR_BLACK 4 -#define MTG_COLOR_WHITE 5 -#define MTG_COLOR_LAND 6 - - -static char MTGColorChars[] = {'x','g','u','r','b','w','l'}; -static const char * MTGColorStrings[] = {"artifact", "green", "blue", "red", "black", "white", "land"}; - -static int _r[7] = {75, 20, 20, 200,50,255,128}; -static int _g[7] = {30, 140, 30, 15, 50,255,128}; -static int _b[7] = {20, 0, 140,15, 50,255,128}; - - -#define MTG_UNCOLORED 0 -#define MTG_FOREST 1 -#define MTG_ISLAND 2 -#define MTG_MOUNTAIN 3 -#define MTG_SWAMP 4 -#define MTG_PLAIN 5 - -#define MTG_TYPE_CREATURE 10 -#define MTG_TYPE_ARTIFACT 11 -#define MTG_TYPE_ENCHANTMENT 12 -#define MTG_TYPE_SORCERY 13 -#define MTG_TYPE_LAND 14 -#define MTG_TYPE_INSTANT 15 - - - -#define MTG_PHASE_BEFORE_BEGIN 0 -#define MTG_PHASE_UNTAP 1 -#define MTG_PHASE_UPKEEP 2 -#define MTG_PHASE_DRAW 3 -#define MTG_PHASE_FIRSTMAIN 4 -#define MTG_PHASE_COMBATBEGIN 5 -#define MTG_PHASE_COMBATATTACKERS 6 -#define MTG_PHASE_COMBATBLOCKERS 7 -#define MTG_PHASE_COMBATDAMAGE 8 -#define MTG_PHASE_COMBATEND 9 -#define MTG_PHASE_SECONDMAIN 10 -#define MTG_PHASE_ENDOFTURN 11 -#define MTG_PHASE_EOT 11 -#define MTG_PHASE_CLEANUP 12 -#define MTG_PHASE_AFTER_EOT 13 -#define NB_MTG_PHASES 14 - -#define TRAMPLE 0 -#define FORESTWALK 1 -#define ISLANDWALK 2 -#define MOUNTAINWALK 3 -#define SWAMPWALK 4 -#define PLAINSWALK 5 -#define FLYING 6 -#define FIRSTSTRIKE 7 -#define DOUBLESTRIKE 8 -#define FEAR 9 -#define FLASH 10 -#define HASTE 11 -#define LIFELINK 12 -#define REACH 13 -#define SHROUD 14 -#define VIGILANCE 15 -#define DEFENSER 16 -#define DEFENDER 16 -#define BANDING 17 -#define PROTECTIONGREEN 18 -#define PROTECTIONBLUE 19 -#define PROTECTIONRED 20 -#define PROTECTIONBLACK 21 -#define PROTECTIONWHITE 22 -#define UNBLOCKABLE 23 -#define WITHER 24 -#define PERSIST 25 -#define RETRACE 26 -#define EXALTED 27 -#define LEGENDARY 28 -#define SHADOW 29 -#define REACHSHADOW 30 -#define FORESTHOME 31 -#define ISLANDHOME 32 -#define MOUNTAINHOME 33 -#define SWAMPHOME 34 -#define PLAINSHOME 35 -#define FLANKING 36 -#define RAMPAGE1 37 - -#define NB_BASIC_ABILITIES 38 - -static const char * MTGBasicAbilities[] = { -"trample", -"forestwalk", -"islandwalk", -"mountainwalk", -"swampwalk", -"plainwalk", -"flying", -"first strike", -"double strike", -"fear", -"flash", -"haste", -"lifelink", -"reach", -"shroud", -"vigilance", -"defender", -"banding", -"protection from green", -"protection from blue", -"protection from red", -"protection from black", -"protection from white", -"unblockable", -"wither", -"persist", -"retrace", -"exalted", -"legendary", -"shadow", -"reachshadow", -"foresthome", -"islandhome", -"moutainhome", -"swamphome", -"plainshome", -"flanking", -"rampage", -}; - - -#define RARITY_M 'M' -#define RARITY_R 'R' -#define RARITY_U 'U' -#define RARITY_C 'C' -#define RARITY_L 'L' - - -#define MAIN_FONT 0 -#define MAGIC_FONT 1 - - -static const char *MTGPhaseNames[] = -{ - "---", - "Untap", - "Upkeep", - "Draw", - "Main phase 1", - "Combat begins", - "Attackers", - "Blockers", - "Combat damage", - "Combat ends", - "Main phase 2", - "End of turn", - "cleanup", - "---" -}; - - - - - -#endif +#ifndef _MTGDEFINITION_H_ +#define _MTGDEFINITION_H_ + + +#define TOTAL_NUMBER_OF_CARDS 4000 + +#define MTG_NB_COLORS 7 + +#define MTG_COLOR_ARTIFACT 0 +#define MTG_COLOR_GREEN 1 +#define MTG_COLOR_BLUE 2 +#define MTG_COLOR_RED 3 +#define MTG_COLOR_BLACK 4 +#define MTG_COLOR_WHITE 5 +#define MTG_COLOR_LAND 6 + + +static char MTGColorChars[] = {'x','g','u','r','b','w','l'}; +static const char * MTGColorStrings[] = {"artifact", "green", "blue", "red", "black", "white", "land"}; + +static int _r[7] = {75, 20, 20, 200,50,255,128}; +static int _g[7] = {30, 140, 30, 15, 50,255,128}; +static int _b[7] = {20, 0, 140,15, 50,255,128}; + + +#define MTG_UNCOLORED 0 +#define MTG_FOREST 1 +#define MTG_ISLAND 2 +#define MTG_MOUNTAIN 3 +#define MTG_SWAMP 4 +#define MTG_PLAIN 5 + +#define MTG_TYPE_CREATURE 10 +#define MTG_TYPE_ARTIFACT 11 +#define MTG_TYPE_ENCHANTMENT 12 +#define MTG_TYPE_SORCERY 13 +#define MTG_TYPE_LAND 14 +#define MTG_TYPE_INSTANT 15 + + + +#define MTG_PHASE_BEFORE_BEGIN 0 +#define MTG_PHASE_UNTAP 1 +#define MTG_PHASE_UPKEEP 2 +#define MTG_PHASE_DRAW 3 +#define MTG_PHASE_FIRSTMAIN 4 +#define MTG_PHASE_COMBATBEGIN 5 +#define MTG_PHASE_COMBATATTACKERS 6 +#define MTG_PHASE_COMBATBLOCKERS 7 +#define MTG_PHASE_COMBATDAMAGE 8 +#define MTG_PHASE_COMBATEND 9 +#define MTG_PHASE_SECONDMAIN 10 +#define MTG_PHASE_ENDOFTURN 11 +#define MTG_PHASE_EOT 11 +#define MTG_PHASE_CLEANUP 12 +#define MTG_PHASE_AFTER_EOT 13 +#define NB_MTG_PHASES 14 + +#define TRAMPLE 0 +#define FORESTWALK 1 +#define ISLANDWALK 2 +#define MOUNTAINWALK 3 +#define SWAMPWALK 4 +#define PLAINSWALK 5 +#define FLYING 6 +#define FIRSTSTRIKE 7 +#define DOUBLESTRIKE 8 +#define FEAR 9 +#define FLASH 10 +#define HASTE 11 +#define LIFELINK 12 +#define REACH 13 +#define SHROUD 14 +#define VIGILANCE 15 +#define DEFENSER 16 +#define DEFENDER 16 +#define BANDING 17 +#define PROTECTIONGREEN 18 +#define PROTECTIONBLUE 19 +#define PROTECTIONRED 20 +#define PROTECTIONBLACK 21 +#define PROTECTIONWHITE 22 +#define UNBLOCKABLE 23 +#define WITHER 24 +#define PERSIST 25 +#define RETRACE 26 +#define EXALTED 27 +#define LEGENDARY 28 +#define SHADOW 29 +#define REACHSHADOW 30 +#define FORESTHOME 31 +#define ISLANDHOME 32 +#define MOUNTAINHOME 33 +#define SWAMPHOME 34 +#define PLAINSHOME 35 +#define FLANKING 36 +#define RAMPAGE1 37 + +#define NB_BASIC_ABILITIES 38 + +static const char * MTGBasicAbilities[] = { + "trample", + "forestwalk", + "islandwalk", + "mountainwalk", + "swampwalk", + "plainwalk", + "flying", + "first strike", + "double strike", + "fear", + "flash", + "haste", + "lifelink", + "reach", + "shroud", + "vigilance", + "defender", + "banding", + "protection from green", + "protection from blue", + "protection from red", + "protection from black", + "protection from white", + "unblockable", + "wither", + "persist", + "retrace", + "exalted", + "legendary", + "shadow", + "reachshadow", + "foresthome", + "islandhome", + "moutainhome", + "swamphome", + "plainshome", + "flanking", + "rampage", +}; + + +#define RARITY_M 'M' +#define RARITY_R 'R' +#define RARITY_U 'U' +#define RARITY_C 'C' +#define RARITY_L 'L' + + +#define MAIN_FONT 0 +#define MAGIC_FONT 1 + + +static const char *MTGPhaseNames[] = + { + "---", + "Untap", + "Upkeep", + "Draw", + "Main phase 1", + "Combat begins", + "Attackers", + "Blockers", + "Combat damage", + "Combat ends", + "Main phase 2", + "End of turn", + "cleanup", + "---" + }; + + + + + +#endif diff --git a/projects/mtg/include/MTGGamePhase.h b/projects/mtg/include/MTGGamePhase.h index 1b7ff267f..af5f75fff 100644 --- a/projects/mtg/include/MTGGamePhase.h +++ b/projects/mtg/include/MTGGamePhase.h @@ -14,10 +14,10 @@ class MTGGamePhase: public ActionElement { int currentState; JLBFont * mFont; public: -MTGGamePhase(int id); + MTGGamePhase(int id); virtual void Render(); virtual void Update(float dt); - void CheckUserInput(float dt); + void CheckUserInput(float dt); }; diff --git a/projects/mtg/include/MTGGameZones.h b/projects/mtg/include/MTGGameZones.h index b9417c503..2074f427e 100644 --- a/projects/mtg/include/MTGGameZones.h +++ b/projects/mtg/include/MTGGameZones.h @@ -1,98 +1,98 @@ -#ifndef _MTGGAMEZONES_H_ -#define _MTGGAMEZONES_H_ - -#include -using std::map; - -#include "MTGDeck.h" -#include "MTGCardInstance.h" - -#define MTG_MAX_PLAYER_CARDS 100 - -class MTGAllCards; -class MTGCardInstance; -class Player; - -class MTGGameZone { - protected: - Player * owner; - public: - //Both cards and cardsMap contain the cards of a zone. The long term objective is to get rid of the array - MTGCardInstance * cards[MTG_MAX_PLAYER_CARDS]; - map cardsMap; - int nb_cards; - MTGGameZone(); - ~MTGGameZone(); - void shuffle(); - virtual MTGCardInstance * draw(); - void addCard(MTGCardInstance * card); - void debugPrint(); - MTGCardInstance * removeCard(MTGCardInstance * card); - MTGCardInstance * hasCard(MTGCardInstance * card); - void cleanupPhase(); - int countByType(const char * value); - int hasType(const char * value); - void setOwner(Player * player); - MTGCardInstance * lastCardDrawn; -}; - -class MTGLibrary: public MTGGameZone { - public: - // MTGLibrary(); - void shuffleTopToBottom(int nbcards); - MTGCardInstance * draw(); -}; - -class MTGGraveyard: public MTGGameZone { - public: - // MTGGraveyard(); -}; - -class MTGHand: public MTGGameZone { - public: -}; - - -class MTGStack: public MTGGameZone { -public: -}; - -class MTGInPlay: public MTGGameZone { - public: - //MTGInPlay(); - void untapAll(); - MTGCardInstance * getNextAttacker(MTGCardInstance * previous); - MTGCardInstance * getNextDefenser(MTGCardInstance * previous, MTGCardInstance * attacker); - int nbDefensers( MTGCardInstance * attacker); - int nbPartners(MTGCardInstance * attacker); -}; - - -class MTGPlayerCards { - protected: - void init(); - - public: - MTGLibrary * library; - MTGGraveyard * graveyard; - MTGHand * hand; - MTGInPlay * inPlay; - MTGStack * stack; - MTGAllCards * collection; - - MTGPlayerCards(MTGAllCards * _collection, int * idList, int idListSize); - ~MTGPlayerCards(); - void initGame(int shuffle = 1, int draw = 1); - void setOwner(Player * player); - void discardRandom(MTGGameZone * from); - void drawFromLibrary(); - void showHand(); - void putInGraveyard(MTGCardInstance * card); - void putInZone(MTGCardInstance * card, MTGGameZone * from, MTGGameZone * to); - void putInPlay(MTGCardInstance * card); - int isInPlay(MTGCardInstance * card); - -}; - - -#endif +#ifndef _MTGGAMEZONES_H_ +#define _MTGGAMEZONES_H_ + +#include +using std::map; + +#include "MTGDeck.h" +#include "MTGCardInstance.h" + +#define MTG_MAX_PLAYER_CARDS 100 + +class MTGAllCards; +class MTGCardInstance; +class Player; + +class MTGGameZone { + protected: + Player * owner; + public: + //Both cards and cardsMap contain the cards of a zone. The long term objective is to get rid of the array + MTGCardInstance * cards[MTG_MAX_PLAYER_CARDS]; + map cardsMap; + int nb_cards; + MTGGameZone(); + ~MTGGameZone(); + void shuffle(); + virtual MTGCardInstance * draw(); + void addCard(MTGCardInstance * card); + void debugPrint(); + MTGCardInstance * removeCard(MTGCardInstance * card); + MTGCardInstance * hasCard(MTGCardInstance * card); + void cleanupPhase(); + int countByType(const char * value); + int hasType(const char * value); + void setOwner(Player * player); + MTGCardInstance * lastCardDrawn; +}; + +class MTGLibrary: public MTGGameZone { + public: + // MTGLibrary(); + void shuffleTopToBottom(int nbcards); + MTGCardInstance * draw(); +}; + +class MTGGraveyard: public MTGGameZone { + public: + // MTGGraveyard(); +}; + +class MTGHand: public MTGGameZone { + public: +}; + + +class MTGStack: public MTGGameZone { + public: +}; + +class MTGInPlay: public MTGGameZone { + public: + //MTGInPlay(); + void untapAll(); + MTGCardInstance * getNextAttacker(MTGCardInstance * previous); + MTGCardInstance * getNextDefenser(MTGCardInstance * previous, MTGCardInstance * attacker); + int nbDefensers( MTGCardInstance * attacker); + int nbPartners(MTGCardInstance * attacker); +}; + + +class MTGPlayerCards { + protected: + void init(); + + public: + MTGLibrary * library; + MTGGraveyard * graveyard; + MTGHand * hand; + MTGInPlay * inPlay; + MTGStack * stack; + MTGAllCards * collection; + + MTGPlayerCards(MTGAllCards * _collection, int * idList, int idListSize); + ~MTGPlayerCards(); + void initGame(int shuffle = 1, int draw = 1); + void setOwner(Player * player); + void discardRandom(MTGGameZone * from); + void drawFromLibrary(); + void showHand(); + void putInGraveyard(MTGCardInstance * card); + void putInZone(MTGCardInstance * card, MTGGameZone * from, MTGGameZone * to); + void putInPlay(MTGCardInstance * card); + int isInPlay(MTGCardInstance * card); + +}; + + +#endif diff --git a/projects/mtg/include/MTGGuiHand.h b/projects/mtg/include/MTGGuiHand.h index 7c8320b1a..3c7f67ec9 100644 --- a/projects/mtg/include/MTGGuiHand.h +++ b/projects/mtg/include/MTGGuiHand.h @@ -17,7 +17,7 @@ class GuiCardscontroller; class MTGGuiHand: public GuiCardsController{ protected: - int currentId[2]; + int currentId[2]; Player * currentPlayer; int mShowHand; float mAnimState; diff --git a/projects/mtg/include/MTGGuiPlay.h b/projects/mtg/include/MTGGuiPlay.h index 37f38d3c5..7388d3bbf 100644 --- a/projects/mtg/include/MTGGuiPlay.h +++ b/projects/mtg/include/MTGGuiPlay.h @@ -11,42 +11,42 @@ class GameObserver; class CardGui; class MTGGuiPlay: public PlayGuiObjectController { -protected: - int offset; - Player * currentPlayer; - MTGCardInstance * cardsGrid[SCREEN_WIDTH/5][SCREEN_HEIGHT/5]; - int nb_creatures; - int nb_spells; - int nb_lands; - int cards_x_limit; + protected: + int offset; + Player * currentPlayer; + MTGCardInstance * cardsGrid[SCREEN_WIDTH/5][SCREEN_HEIGHT/5]; + int nb_creatures; + int nb_spells; + int nb_lands; + int cards_x_limit; - JQuad * phaseIcons[24]; - JQuad * mGlitter; - int mGlitterAlpha; - float mGlitterX, mGlitterY; - JTexture * mPhaseBarTexture; - JQuad * mIcons[7]; - JTexture * mIconsTexture; - JTexture * mBgTex; - JQuad * mBg; + JQuad * phaseIcons[24]; + JQuad * mGlitter; + int mGlitterAlpha; + float mGlitterX, mGlitterY; + JTexture * mPhaseBarTexture; + JQuad * mIcons[7]; + JTexture * mIconsTexture; + JTexture * mBgTex; + JQuad * mBg; - JTexture * mBgTex2; - JQuad * mBg2; - int alphaBg[4]; - void RenderPhaseBar(); - void RenderPlayerInfo(int player); - JLBFont* mFont; + JTexture * mBgTex2; + JQuad * mBg2; + int alphaBg[4]; + void RenderPhaseBar(); + void RenderPlayerInfo(int player); + JLBFont* mFont; - void AddPlayersGuiInfo(); - void initCardsDisplay(); - void setCardPosition(CardGui * cardg, int player, int playerTurn, int spellMode); - void setTargettingCardPosition(CardGui * cardg, int player, int playerTurn); - void adjustCardPosition(CardGui * cardg); -public: -CardGui * getByCard(MTGCardInstance * card); - MTGGuiPlay(int id, GameObserver * game); - ~MTGGuiPlay(); - void Update(float dt); + void AddPlayersGuiInfo(); + void initCardsDisplay(); + void setCardPosition(CardGui * cardg, int player, int playerTurn, int spellMode); + void setTargettingCardPosition(CardGui * cardg, int player, int playerTurn); + void adjustCardPosition(CardGui * cardg); + public: + CardGui * getByCard(MTGCardInstance * card); + MTGGuiPlay(int id, GameObserver * game); + ~MTGGuiPlay(); + void Update(float dt); void CheckUserInput(float dt); virtual void Render(); void updateCards(); diff --git a/projects/mtg/include/MTGRules.h b/projects/mtg/include/MTGRules.h index 2a60c19f0..b1da65954 100644 --- a/projects/mtg/include/MTGRules.h +++ b/projects/mtg/include/MTGRules.h @@ -1,120 +1,120 @@ -/* Default observers/Abilities that are added to the game for a standard Magic Game -*/ - -#ifndef _MTGRULES_H_ -#define _MTGRULES_H_ - -#include "../include/MTGAbility.h" -#include "../include/Counters.h" - - -class MTGAttackRule:public MTGAbility{ -public: - int isReactingToClick(MTGCardInstance * card); - int reactToClick(MTGCardInstance * card); - int testDestroy(); - MTGAttackRule(int _id); - const char * getMenuText(){return "Attacker";} - -}; - -class MTGBlockRule:public MTGAbility{ -public: - int isReactingToClick(MTGCardInstance * card); - int reactToClick(MTGCardInstance * card); - int testDestroy(); - MTGBlockRule(int _id); - const char * getMenuText(){return "Blocker";} -}; - - -/* Persist Rule */ -class MTGPersistRule:public ListMaintainerAbility{ -public: - MTGPersistRule(int _id):ListMaintainerAbility(_id){}; - - virtual void Update(float dt){ - map::iterator it; - - for ( it=cards.begin() ; it != cards.end(); it++ ){ - MTGCardInstance * card = ((*it).first); - Player * p = card->controller(); - if (p->game->graveyard->hasCard(card)){ -#if defined (WIN32) || defined (LINUX) - OutputDebugString("persist passed test 1 !\n"); -#endif - p->game->putInZone(card, p->game->graveyard, p->game->hand); - Spell * spell = NEW Spell(card); - p->game->putInZone(card, p->game->hand, p->game->stack); - spell->resolve(); - delete spell; -#if defined (WIN32) || defined (LINUX) - OutputDebugString("persist passed test 2 !\n"); -#endif - card->counters->addCounter(-1,-1); -#if defined (WIN32) || defined (LINUX) - OutputDebugString("persist passed test 3 !\n"); -#endif - } - } - ListMaintainerAbility::Update(dt); - } - - int canBeInList(MTGCardInstance * card){ - if (card->basicAbilities[PERSIST] && !card->counters->hasCounter(-1,-1) ){ -#if defined (WIN32) || defined (LINUX) - OutputDebugString("yay, persist !\n"); -#endif - return 1; - } - return 0; - } - - int added(MTGCardInstance * card){return 1;} - - int removed(MTGCardInstance * card){return 0;} - - int testDestroy(){return 0;} -}; - - - -/* - * Rule 420.5e (Legend Rule) - * If two or more legendary permanents with the same name are in play, all are put into their - * owners' graveyards. This is called the "legend rule." If only one of those permanents is - * legendary, this rule doesn't apply. -*/ -class MTGLegendRule:public ListMaintainerAbility{ -public: - MTGLegendRule(int _id):ListMaintainerAbility(_id){}; - - int canBeInList(MTGCardInstance * card){ - if (card->basicAbilities[LEGENDARY]){ - return 1; - } - return 0; - } - - int added(MTGCardInstance * card){ - map::iterator it; - int destroy = 0; - for ( it=cards.begin() ; it != cards.end(); it++ ){ - MTGCardInstance * comparison = (*it).first; - if (comparison!= card && !strcmp(comparison->getName(), card->getName())){ - comparison->owner->game->putInGraveyard(comparison); - destroy = 1; - } - } - if (destroy){ - card->owner->game->putInGraveyard(card); - } - return 1; - } - - int removed(MTGCardInstance * card){return 0;} - - int testDestroy(){return 0;} -}; - -#endif +/* Default observers/Abilities that are added to the game for a standard Magic Game + */ + +#ifndef _MTGRULES_H_ +#define _MTGRULES_H_ + +#include "../include/MTGAbility.h" +#include "../include/Counters.h" + + +class MTGAttackRule:public MTGAbility{ + public: + int isReactingToClick(MTGCardInstance * card); + int reactToClick(MTGCardInstance * card); + int testDestroy(); + MTGAttackRule(int _id); + const char * getMenuText(){return "Attacker";} + +}; + +class MTGBlockRule:public MTGAbility{ + public: + int isReactingToClick(MTGCardInstance * card); + int reactToClick(MTGCardInstance * card); + int testDestroy(); + MTGBlockRule(int _id); + const char * getMenuText(){return "Blocker";} +}; + + +/* Persist Rule */ +class MTGPersistRule:public ListMaintainerAbility{ + public: + MTGPersistRule(int _id):ListMaintainerAbility(_id){}; + + virtual void Update(float dt){ + map::iterator it; + + for ( it=cards.begin() ; it != cards.end(); it++ ){ + MTGCardInstance * card = ((*it).first); + Player * p = card->controller(); + if (p->game->graveyard->hasCard(card)){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("persist passed test 1 !\n"); +#endif + p->game->putInZone(card, p->game->graveyard, p->game->hand); + Spell * spell = NEW Spell(card); + p->game->putInZone(card, p->game->hand, p->game->stack); + spell->resolve(); + delete spell; +#if defined (WIN32) || defined (LINUX) + OutputDebugString("persist passed test 2 !\n"); +#endif + card->counters->addCounter(-1,-1); +#if defined (WIN32) || defined (LINUX) + OutputDebugString("persist passed test 3 !\n"); +#endif + } + } + ListMaintainerAbility::Update(dt); + } + + int canBeInList(MTGCardInstance * card){ + if (card->basicAbilities[PERSIST] && !card->counters->hasCounter(-1,-1) ){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("yay, persist !\n"); +#endif + return 1; + } + return 0; + } + + int added(MTGCardInstance * card){return 1;} + + int removed(MTGCardInstance * card){return 0;} + + int testDestroy(){return 0;} +}; + + + +/* + * Rule 420.5e (Legend Rule) + * If two or more legendary permanents with the same name are in play, all are put into their + * owners' graveyards. This is called the "legend rule." If only one of those permanents is + * legendary, this rule doesn't apply. + */ +class MTGLegendRule:public ListMaintainerAbility{ + public: + MTGLegendRule(int _id):ListMaintainerAbility(_id){}; + + int canBeInList(MTGCardInstance * card){ + if (card->basicAbilities[LEGENDARY]){ + return 1; + } + return 0; + } + + int added(MTGCardInstance * card){ + map::iterator it; + int destroy = 0; + for ( it=cards.begin() ; it != cards.end(); it++ ){ + MTGCardInstance * comparison = (*it).first; + if (comparison!= card && !strcmp(comparison->getName(), card->getName())){ + comparison->owner->game->putInGraveyard(comparison); + destroy = 1; + } + } + if (destroy){ + card->owner->game->putInGraveyard(card); + } + return 1; + } + + int removed(MTGCardInstance * card){return 0;} + + int testDestroy(){return 0;} +}; + +#endif diff --git a/projects/mtg/include/ManaCost.h b/projects/mtg/include/ManaCost.h index 010070c4e..da1054037 100644 --- a/projects/mtg/include/ManaCost.h +++ b/projects/mtg/include/ManaCost.h @@ -10,29 +10,29 @@ class ManaCostHybrid; class ManaCost{ protected: int cost[MTG_NB_COLORS+1]; - ManaCostHybrid * hybrids[10]; - int nbhybrids; + ManaCostHybrid * hybrids[10]; + int nbhybrids; public: - static ManaCost * parseManaCost(string value, ManaCost * _manacost = NULL); + static ManaCost * parseManaCost(string value, ManaCost * _manacost = NULL); void init(); - void x(); + void x(); ManaCost(int _cost[], int nb_elems); ManaCost(); - ~ManaCost(); + ~ManaCost(); ManaCost(ManaCost * _manaCost); - void copy (ManaCost * _manaCost); - int getConvertedCost(); + void copy (ManaCost * _manaCost); + int getConvertedCost(); string toString(); int getCost(int color); - int getMainColor(); - int hasColor(int color); - int remove (int color, int value); + int getMainColor(); + int hasColor(int color); + int remove (int color, int value); int add(int color, int value); - int addHybrid(int c1, int v1, int c2, int v2); - int tryToPayHybrids(ManaCostHybrid * _hybrids[], int _nbhybrids, int diff[]); - void randomDiffHybrids(ManaCost * _cost, int diff[]); - int add(ManaCost * _cost); - int pay (ManaCost * _cost); + int addHybrid(int c1, int v1, int c2, int v2); + int tryToPayHybrids(ManaCostHybrid * _hybrids[], int _nbhybrids, int diff[]); + void randomDiffHybrids(ManaCost * _cost, int diff[]); + int add(ManaCost * _cost); + int pay (ManaCost * _cost); //return 1 if _cost can be paid with current data, 0 otherwise int canAfford(ManaCost * _cost); diff --git a/projects/mtg/include/ManaCostHybrid.h b/projects/mtg/include/ManaCostHybrid.h index 920fe1e1a..da4649a7e 100644 --- a/projects/mtg/include/ManaCostHybrid.h +++ b/projects/mtg/include/ManaCostHybrid.h @@ -1,17 +1,17 @@ -#ifndef _MANACOST_HYBRID_H_ -#define _MANACOST_HYBRID_H_ - -class ManaCostHybrid{ -public: - int color1; - int color2; - int value1; - int value2; - ManaCostHybrid(); - int hasColor(int color); - ManaCostHybrid(int c1,int v1,int c2,int v2); - void init(int c1,int v1,int c2,int v2); - int getConvertedCost(); -}; - -#endif \ No newline at end of file +#ifndef _MANACOST_HYBRID_H_ +#define _MANACOST_HYBRID_H_ + +class ManaCostHybrid{ + public: + int color1; + int color2; + int value1; + int value2; + ManaCostHybrid(); + int hasColor(int color); + ManaCostHybrid(int c1,int v1,int c2,int v2); + void init(int c1,int v1,int c2,int v2); + int getConvertedCost(); +}; + +#endif diff --git a/projects/mtg/include/MenuItem.h b/projects/mtg/include/MenuItem.h index c6e73a44b..75fe2ac84 100644 --- a/projects/mtg/include/MenuItem.h +++ b/projects/mtg/include/MenuItem.h @@ -1,43 +1,43 @@ -#ifndef _MENU_ITEM_H -#define _MENU_ITEM_H - -#include -#include -#include - -#define SCALE_SELECTED 1.2f -#define SCALE_NORMAL 1.0f - -class hgeParticleSystem; - -class MenuItem: public JGuiObject -{ -private: - bool mHasFocus; - JLBFont *mFont; - const char* const mText; - int mX; - int mY; - int updatedSinceLastRender; - float lastDt; - - float mScale; - float mTargetScale; - JQuad * onQuad; - JQuad * offQuad; - hgeParticleSystem* mParticleSys; - - -public: - MenuItem(int id, JLBFont *font, const char* text, int x, int y, JQuad * _off, JQuad * _on, const char * particle, JQuad * particleQuad, bool hasFocus = false); - ~MenuItem(); - virtual void Render(); - virtual void Update(float dt); - - virtual void Entering(); - virtual bool Leaving(u32 key); - virtual bool ButtonPressed(); -}; - -#endif - +#ifndef _MENU_ITEM_H +#define _MENU_ITEM_H + +#include +#include +#include + +#define SCALE_SELECTED 1.2f +#define SCALE_NORMAL 1.0f + +class hgeParticleSystem; + +class MenuItem: public JGuiObject +{ + private: + bool mHasFocus; + JLBFont *mFont; + const char* const mText; + int mX; + int mY; + int updatedSinceLastRender; + float lastDt; + + float mScale; + float mTargetScale; + JQuad * onQuad; + JQuad * offQuad; + hgeParticleSystem* mParticleSys; + + + public: + MenuItem(int id, JLBFont *font, const char* text, int x, int y, JQuad * _off, JQuad * _on, const char * particle, JQuad * particleQuad, bool hasFocus = false); + ~MenuItem(); + virtual void Render(); + virtual void Update(float dt); + + virtual void Entering(); + virtual bool Leaving(u32 key); + virtual bool ButtonPressed(); +}; + +#endif + diff --git a/projects/mtg/include/OptionItem.h b/projects/mtg/include/OptionItem.h index a9c72aeaa..9acec7d53 100644 --- a/projects/mtg/include/OptionItem.h +++ b/projects/mtg/include/OptionItem.h @@ -1,40 +1,40 @@ -#ifndef _OPTION_ITEM_H_ -#define _OPTION_ITEM_H_ - -#include -#include - -using std::string; - -class OptionItem:public JGuiObject{ -public: - string displayValue; - int id, value; - int hasFocus; - int maxValue, increment; - float x, y; - OptionItem(int id, string _displayValue, int _maxValue = 1, int _increment = 1); - - ~OptionItem(); - virtual void Render(); - virtual void Update(float dt); - virtual void Entering(); - virtual bool Leaving(); - void setData(); - virtual void updateValue(){value+=increment; if (value>maxValue) value=0;}; -}; - -class OptionsList{ -public: - OptionItem * options[20]; - int nbitems; - int current; - OptionsList(); - ~OptionsList(); - void Render(); - void Update(float dt); - void Add(OptionItem * item); - void save(); -}; - -#endif +#ifndef _OPTION_ITEM_H_ +#define _OPTION_ITEM_H_ + +#include +#include + +using std::string; + +class OptionItem:public JGuiObject{ + public: + string displayValue; + int id, value; + int hasFocus; + int maxValue, increment; + float x, y; + OptionItem(int id, string _displayValue, int _maxValue = 1, int _increment = 1); + + ~OptionItem(); + virtual void Render(); + virtual void Update(float dt); + virtual void Entering(); + virtual bool Leaving(); + void setData(); + virtual void updateValue(){value+=increment; if (value>maxValue) value=0;}; +}; + +class OptionsList{ + public: + OptionItem * options[20]; + int nbitems; + int current; + OptionsList(); + ~OptionsList(); + void Render(); + void Update(float dt); + void Add(OptionItem * item); + void save(); +}; + +#endif diff --git a/projects/mtg/include/PhaseRing.h b/projects/mtg/include/PhaseRing.h index 92987df48..8a2f6fbbb 100644 --- a/projects/mtg/include/PhaseRing.h +++ b/projects/mtg/include/PhaseRing.h @@ -1,34 +1,34 @@ -#ifndef _PHASERING_H_ -#define _PHASERING_H_ - -#include -using std::list; - -/* -The class that handles the phases of a turn -*/ - -class Player; - -class Phase{ -public: - int id; - Player * player; - Phase(int _id, Player * _player):id(_id),player(_player){}; -}; - -class PhaseRing{ -public: - list ring; - list::iterator current; - Phase * getCurrentPhase(); - Phase * forward(); - Phase * goToPhase(int id, Player * player); - PhaseRing(Player* players[], int nbPlayers=2); - ~PhaseRing(); - int addPhase(Phase * phase); - int addPhaseBefore(int id, Player* player,int after_id, Player * after_player, int allOccurences = 1); - int removePhase (int id, Player * player, int allOccurences = 1); -}; - -#endif \ No newline at end of file +#ifndef _PHASERING_H_ +#define _PHASERING_H_ + +#include +using std::list; + +/* + The class that handles the phases of a turn +*/ + +class Player; + +class Phase{ + public: + int id; + Player * player; + Phase(int _id, Player * _player):id(_id),player(_player){}; +}; + +class PhaseRing{ + public: + list ring; + list::iterator current; + Phase * getCurrentPhase(); + Phase * forward(); + Phase * goToPhase(int id, Player * player); + PhaseRing(Player* players[], int nbPlayers=2); + ~PhaseRing(); + int addPhase(Phase * phase); + int addPhaseBefore(int id, Player* player,int after_id, Player * after_player, int allOccurences = 1); + int removePhase (int id, Player * player, int allOccurences = 1); +}; + +#endif diff --git a/projects/mtg/include/PlayGuiObject.h b/projects/mtg/include/PlayGuiObject.h index 999121202..67f1ed5a0 100644 --- a/projects/mtg/include/PlayGuiObject.h +++ b/projects/mtg/include/PlayGuiObject.h @@ -1,78 +1,78 @@ -/* -A class for all interactive objects in the play area (cards, avatars, etc...) -*/ - -#ifndef _PLAYGUIOBJECT_H_ -#define _PLAYGUIOBJECT_H_ - -#define GUI_AVATAR 1 -#define GUI_CARD 2 -#define GUI_GRAVEYARD 3 -#define GUI_LIBRARY 4 - -#include - -class MTGGameZone; -class Player; -class CardDisplay; - -class PlayGuiObject: public JGuiObject, public JGuiListener{ - protected: - - public: - int wave; - float mHeight; - float defaultHeight; - bool mHasFocus; - int x; - int y; - int type; - virtual void Entering(){mHasFocus = true;}; - virtual bool Leaving(u32 key){mHasFocus = false;return true;}; - virtual bool ButtonPressed(){return true;}; - virtual void Render(){}; - virtual void Update(float dt); - PlayGuiObject(int id, float desiredHeight,float _x, float _y, bool hasFocus); - virtual void ButtonPressed(int controllerId, int controlId){}; - virtual ~PlayGuiObject(){}; - -}; - -class GuiAvatar: public PlayGuiObject{ -protected: +/* + A class for all interactive objects in the play area (cards, avatars, etc...) +*/ - int avatarRed; - int currentLife; -public: - Player * player; - virtual void Render(); - GuiAvatar(int id, float desiredHeight,float _x, float _y, bool hasFocus,Player * _player); -}; - -class GuiGameZone: public PlayGuiObject{ -protected: - MTGGameZone * zone; - -public: - CardDisplay * cd; - int showCards; - virtual void Render(); - virtual void Update(float dt); - GuiGameZone(int id, float desiredHeight,float _x, float _y, bool hasFocus,MTGGameZone * _zone); - ~GuiGameZone(); - virtual void ButtonPressed(int controllerId, int controlId); - void toggleDisplay(); -}; - -class GuiGraveyard: public GuiGameZone{ -public: - GuiGraveyard(int id, float desiredHeight,float _x, float _y, bool hasFocus,Player * player); -}; - -class GuiLibrary: public GuiGameZone{ -public: - GuiLibrary(int id, float desiredHeight,float _x, float _y, bool hasFocus,Player * player); -}; - - -#endif \ No newline at end of file +#ifndef _PLAYGUIOBJECT_H_ +#define _PLAYGUIOBJECT_H_ + +#define GUI_AVATAR 1 +#define GUI_CARD 2 +#define GUI_GRAVEYARD 3 +#define GUI_LIBRARY 4 + +#include + +class MTGGameZone; +class Player; +class CardDisplay; + +class PlayGuiObject: public JGuiObject, public JGuiListener{ + protected: + + public: + int wave; + float mHeight; + float defaultHeight; + bool mHasFocus; + int x; + int y; + int type; + virtual void Entering(){mHasFocus = true;}; + virtual bool Leaving(u32 key){mHasFocus = false;return true;}; + virtual bool ButtonPressed(){return true;}; + virtual void Render(){}; + virtual void Update(float dt); + PlayGuiObject(int id, float desiredHeight,float _x, float _y, bool hasFocus); + virtual void ButtonPressed(int controllerId, int controlId){}; + virtual ~PlayGuiObject(){}; + +}; + +class GuiAvatar: public PlayGuiObject{ + protected: + + int avatarRed; + int currentLife; + public: + Player * player; + virtual void Render(); + GuiAvatar(int id, float desiredHeight,float _x, float _y, bool hasFocus,Player * _player); +}; + +class GuiGameZone: public PlayGuiObject{ + protected: + MTGGameZone * zone; + + public: + CardDisplay * cd; + int showCards; + virtual void Render(); + virtual void Update(float dt); + GuiGameZone(int id, float desiredHeight,float _x, float _y, bool hasFocus,MTGGameZone * _zone); + ~GuiGameZone(); + virtual void ButtonPressed(int controllerId, int controlId); + void toggleDisplay(); +}; + +class GuiGraveyard: public GuiGameZone{ + public: + GuiGraveyard(int id, float desiredHeight,float _x, float _y, bool hasFocus,Player * player); +}; + +class GuiLibrary: public GuiGameZone{ + public: + GuiLibrary(int id, float desiredHeight,float _x, float _y, bool hasFocus,Player * player); +}; + + +#endif diff --git a/projects/mtg/include/PlayGuiObjectController.h b/projects/mtg/include/PlayGuiObjectController.h index 4e9aa8fd2..baad25d57 100644 --- a/projects/mtg/include/PlayGuiObjectController.h +++ b/projects/mtg/include/PlayGuiObjectController.h @@ -1,6 +1,6 @@ -#ifndef _PLAYGUIOBJECTCONTROLLER_H_ -#define _PLAYGUIOBJECTCONTROLLER_H_ - +#ifndef _PLAYGUIOBJECTCONTROLLER_H_ +#define _PLAYGUIOBJECTCONTROLLER_H_ + #include "GuiLayers.h" @@ -8,14 +8,14 @@ class PlayGuiObjectController : public GuiLayer{ protected: int getClosestItem(int direction); int getClosestItem(int direction, float tolerance); - static bool showBigCards; + static bool showBigCards; 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){}; virtual void Render(){GuiLayer::Render();}; }; - - -#endif \ No newline at end of file + + +#endif diff --git a/projects/mtg/include/Player.h b/projects/mtg/include/Player.h index 6f275fd0a..cccc4d9d1 100644 --- a/projects/mtg/include/Player.h +++ b/projects/mtg/include/Player.h @@ -15,33 +15,33 @@ class Player: public Damageable, public Targetable{ ManaCost * manaPool; public: - int typeAsTarget(){return TARGET_PLAYER;} - virtual int displayStack(){return 1;} + int typeAsTarget(){return TARGET_PLAYER;} + virtual int displayStack(){return 1;} JTexture * mAvatarTex; JQuad * mAvatar; int canPutLandsIntoPlay; - MTGPlayerCards * game; - int testLife(); - int afterDamage(); + MTGPlayerCards * game; + int testLife(); + int afterDamage(); Player(MTGPlayerCards * _deck, string deckFile); - virtual ~Player(); + virtual ~Player(); void unTapPhase(); MTGInPlay * inPlay(); ManaCost * getManaPool(); - int manaBurn(); - void cleanupPhase(); - virtual int Act(float dt){return 0;}; - virtual int isAI(){return 0;}; - Player * opponent(); - int getId(); - JQuad * getIcon(); - string deckFile; + int manaBurn(); + void cleanupPhase(); + virtual int Act(float dt){return 0;}; + virtual int isAI(){return 0;}; + Player * opponent(); + int getId(); + JQuad * getIcon(); + string deckFile; }; class HumanPlayer: public Player{ public: HumanPlayer(MTGPlayerCards * _deck, char * _deckFile); - + }; diff --git a/projects/mtg/include/PlayerData.h b/projects/mtg/include/PlayerData.h index b7ddf7437..2856c0c4f 100644 --- a/projects/mtg/include/PlayerData.h +++ b/projects/mtg/include/PlayerData.h @@ -1,18 +1,18 @@ -#ifndef _PLAYER_DATA_H_ -#define _PLAYER_DATA_H_ - -#define PLAYER_SAVEFILE "Res/player/data.dat" - -#include "../include/MTGDeck.h" - -class PlayerData{ -protected: -public: - int credits; - MTGDeck * collection; - PlayerData(MTGAllCards * allcards); - ~PlayerData(); - int save(); -}; - -#endif \ No newline at end of file +#ifndef _PLAYER_DATA_H_ +#define _PLAYER_DATA_H_ + +#define PLAYER_SAVEFILE "Res/player/data.dat" + +#include "../include/MTGDeck.h" + +class PlayerData{ + protected: + public: + int credits; + MTGDeck * collection; + PlayerData(MTGAllCards * allcards); + ~PlayerData(); + int save(); +}; + +#endif diff --git a/projects/mtg/include/PriceList.h b/projects/mtg/include/PriceList.h index db34a7157..5fc457603 100644 --- a/projects/mtg/include/PriceList.h +++ b/projects/mtg/include/PriceList.h @@ -1,31 +1,31 @@ -#ifndef _PRICELIST_H_ -#define _PRICELIST_H_ - -#include -#include "../include/MTGDefinitions.h" -#include "../include/MTGDeck.h" -#include - -class Price{ -public: - int cardid; - int price; - Price(int _cardid, int _price); -}; - -class PriceList{ -private: - MTGAllCards * collection; - string filename; - Price * prices[TOTAL_NUMBER_OF_CARDS]; - int nbprices; -public: - PriceList(const char * file, MTGAllCards * _collection); - ~PriceList(); - int save(); - int getPrice(int cardId); - int setPrice(int cardId, int price); - -}; - -#endif +#ifndef _PRICELIST_H_ +#define _PRICELIST_H_ + +#include +#include "../include/MTGDefinitions.h" +#include "../include/MTGDeck.h" +#include + +class Price{ + public: + int cardid; + int price; + Price(int _cardid, int _price); +}; + +class PriceList{ + private: + MTGAllCards * collection; + string filename; + Price * prices[TOTAL_NUMBER_OF_CARDS]; + int nbprices; + public: + PriceList(const char * file, MTGAllCards * _collection); + ~PriceList(); + int save(); + int getPrice(int cardId); + int setPrice(int cardId, int price); + +}; + +#endif diff --git a/projects/mtg/include/ShopItem.h b/projects/mtg/include/ShopItem.h index cd98be176..44801f8dc 100644 --- a/projects/mtg/include/ShopItem.h +++ b/projects/mtg/include/ShopItem.h @@ -1,71 +1,71 @@ -#ifndef _SHOP_ITEM_H -#define _SHOP_ITEM_H - -#include -#include -#include "SimpleMenu.h" -#include "MTGDeck.h" -#include "../include/PriceList.h" -#include "../include/PlayerData.h" -#include "../include/CardDisplay.h" - -#include -using std::string; - -class ShopItem:public JGuiObject{ -private: - bool mHasFocus; - JLBFont *mFont; - string mText; - int mX; - int mY; - JQuad * quad; - JQuad * thumb; - float mScale; - float mTargetScale; - -public: - int quantity; - MTGCard * card; - int price; - ShopItem(int id, JLBFont * font, int _cardid, int x, int y, bool hasFocus, MTGAllCards * collection, int _price); - ShopItem(int id, JLBFont * font, char* text, JQuad * _quad, JQuad * _thumb,int x, int y, bool hasFocus, int _price); - ~ShopItem(); - - virtual void Render(); - virtual void Update(float dt); - - virtual void Entering(); - virtual bool Leaving(u32 key); - virtual bool ButtonPressed(); - - const char * getText(); -}; - -class ShopItems:public JGuiController,public JGuiListener{ -private: - PlayerData * playerdata; - PriceList * pricelist; - int mX, mY, mHeight; - JLBFont* mFont; - MTGAllCards * collection; - SimpleMenu * dialog; - int showPriceDialog; - int setId; - MTGCardInstance * displayCards[100]; - CardDisplay * display; - void safeDeleteDisplay(); -public: - ShopItems(int id, JGuiListener* listener, JLBFont* font, int x, int y, MTGAllCards * _collection, int setId); - ~ShopItems(); - void Render(); - virtual void Update(float dt); - void Add(int cardid); - void Add(char * text, JQuad * quad, JQuad * thumb,int _price); - void pricedialog(int id, int mode=1); - virtual void ButtonPressed(int controllerId, int controlId); - void savePriceList(); - void saveAll(); -}; - -#endif +#ifndef _SHOP_ITEM_H +#define _SHOP_ITEM_H + +#include +#include +#include "SimpleMenu.h" +#include "MTGDeck.h" +#include "../include/PriceList.h" +#include "../include/PlayerData.h" +#include "../include/CardDisplay.h" + +#include +using std::string; + +class ShopItem:public JGuiObject{ + private: + bool mHasFocus; + JLBFont *mFont; + string mText; + int mX; + int mY; + JQuad * quad; + JQuad * thumb; + float mScale; + float mTargetScale; + + public: + int quantity; + MTGCard * card; + int price; + ShopItem(int id, JLBFont * font, int _cardid, int x, int y, bool hasFocus, MTGAllCards * collection, int _price); + ShopItem(int id, JLBFont * font, char* text, JQuad * _quad, JQuad * _thumb,int x, int y, bool hasFocus, int _price); + ~ShopItem(); + + virtual void Render(); + virtual void Update(float dt); + + virtual void Entering(); + virtual bool Leaving(u32 key); + virtual bool ButtonPressed(); + + const char * getText(); +}; + +class ShopItems:public JGuiController,public JGuiListener{ + private: + PlayerData * playerdata; + PriceList * pricelist; + int mX, mY, mHeight; + JLBFont* mFont; + MTGAllCards * collection; + SimpleMenu * dialog; + int showPriceDialog; + int setId; + MTGCardInstance * displayCards[100]; + CardDisplay * display; + void safeDeleteDisplay(); + public: + ShopItems(int id, JGuiListener* listener, JLBFont* font, int x, int y, MTGAllCards * _collection, int setId); + ~ShopItems(); + void Render(); + virtual void Update(float dt); + void Add(int cardid); + void Add(char * text, JQuad * quad, JQuad * thumb,int _price); + void pricedialog(int id, int mode=1); + virtual void ButtonPressed(int controllerId, int controlId); + void savePriceList(); + void saveAll(); +}; + +#endif diff --git a/projects/mtg/include/SimpleMenu.h b/projects/mtg/include/SimpleMenu.h index 3810aebd8..5dc7d7226 100644 --- a/projects/mtg/include/SimpleMenu.h +++ b/projects/mtg/include/SimpleMenu.h @@ -1,24 +1,24 @@ -/* -A class for very simple menus structure -*/ -#ifndef _SIMPLEMENU_H_ -#define _SIMPLEMENU_H_ - -#include -#include -#include - -class SimpleMenu:public JGuiController{ -private: - int mHeight, mWidth, mX, mY; - JLBFont* mFont; - std::string title; - int displaytitle; -public: - SimpleMenu(int id, JGuiListener* listener, JLBFont* font, int x, int y, int width, const char * _title = NULL); - void Render(); - void Add(int id, const char * Text); -}; - - -#endif +/* + A class for very simple menus structure +*/ +#ifndef _SIMPLEMENU_H_ +#define _SIMPLEMENU_H_ + +#include +#include +#include + +class SimpleMenu:public JGuiController{ + private: + int mHeight, mWidth, mX, mY; + JLBFont* mFont; + std::string title; + int displaytitle; + public: + SimpleMenu(int id, JGuiListener* listener, JLBFont* font, int x, int y, int width, const char * _title = NULL); + void Render(); + void Add(int id, const char * Text); +}; + + +#endif diff --git a/projects/mtg/include/SimpleMenuItem.h b/projects/mtg/include/SimpleMenuItem.h index 755b95136..e93d0a88f 100644 --- a/projects/mtg/include/SimpleMenuItem.h +++ b/projects/mtg/include/SimpleMenuItem.h @@ -1,37 +1,37 @@ -#ifndef _SIMPLEMENU_ITEM_H -#define _SIMPLEMENU_ITEM_H - -#include -#include - -#define SCALE_SELECTED 1.2f -#define SCALE_NORMAL 1.0f - - -class SimpleMenuItem: public JGuiObject -{ -private: - bool mHasFocus; - JLBFont *mFont; - const char* mText; - int mX; - int mY; - - float mScale; - float mTargetScale; - - - -public: - SimpleMenuItem(int id, JLBFont *font, const char* text, int x, int y, bool hasFocus = false); - - virtual void Render(); - virtual void Update(float dt); - - virtual void Entering(); - virtual bool Leaving(u32 key); - virtual bool ButtonPressed(); -}; - -#endif - +#ifndef _SIMPLEMENU_ITEM_H +#define _SIMPLEMENU_ITEM_H + +#include +#include + +#define SCALE_SELECTED 1.2f +#define SCALE_NORMAL 1.0f + + +class SimpleMenuItem: public JGuiObject +{ + private: + bool mHasFocus; + JLBFont *mFont; + const char* mText; + int mX; + int mY; + + float mScale; + float mTargetScale; + + + + public: + SimpleMenuItem(int id, JLBFont *font, const char* text, int x, int y, bool hasFocus = false); + + virtual void Render(); + virtual void Update(float dt); + + virtual void Entering(); + virtual bool Leaving(u32 key); + virtual bool ButtonPressed(); +}; + +#endif + diff --git a/projects/mtg/include/Subtypes.h b/projects/mtg/include/Subtypes.h index 14aaa935c..cf20e25ed 100644 --- a/projects/mtg/include/Subtypes.h +++ b/projects/mtg/include/Subtypes.h @@ -1,25 +1,25 @@ -#ifndef _SUBTYPES_H_ -#define _SUBTYPES_H_ - - -#include -#include -using std::string; -using std::map; - -class Subtypes{ -protected: - int nb_items; - map values; - -public: - static Subtypes * subtypesList; - Subtypes(); - int Add(const char * subtype); - int find(const char * subtype); - int Add(string subtype); - int find(string subtype); -}; - - -#endif \ No newline at end of file +#ifndef _SUBTYPES_H_ +#define _SUBTYPES_H_ + + +#include +#include +using std::string; +using std::map; + +class Subtypes{ + protected: + int nb_items; + map values; + + public: + static Subtypes * subtypesList; + Subtypes(); + int Add(const char * subtype); + int find(const char * subtype); + int Add(string subtype); + int find(string subtype); +}; + + +#endif diff --git a/projects/mtg/include/TargetChooser.h b/projects/mtg/include/TargetChooser.h index b32577df1..0136893a1 100644 --- a/projects/mtg/include/TargetChooser.h +++ b/projects/mtg/include/TargetChooser.h @@ -23,22 +23,22 @@ class CardDescriptor; class TargetChooser: public TargetsList { -protected: - int forceTargetListReady; + protected: + int forceTargetListReady; -public: - TargetChooser(MTGCardInstance * card = NULL, int _maxtargets = -1); + public: + TargetChooser(MTGCardInstance * card = NULL, int _maxtargets = -1); - MTGCardInstance * source; //Optionnal source, used for protection from... - int maxtargets; //Set to -1 for "unlimited" + MTGCardInstance * source; //Optionnal source, used for protection from... + int maxtargets; //Set to -1 for "unlimited" - int ForceTargetListReady(); - int targetsReadyCheck(); - virtual int addTarget(Targetable * target); - virtual int canTarget(Targetable * _target); - virtual int full(){if (maxtargets != -1 && cursor>=maxtargets) {return 1;} else{return 0;}}; - virtual int ready(){return cursor;}; - int targetListSet(); + int ForceTargetListReady(); + int targetsReadyCheck(); + virtual int addTarget(Targetable * target); + virtual int canTarget(Targetable * _target); + virtual int full(){if (maxtargets != -1 && cursor>=maxtargets) {return 1;} else{return 0;}}; + virtual int ready(){return cursor;}; + int targetListSet(); }; @@ -46,94 +46,94 @@ public: class TargetChooserFactory{ public: - TargetChooser * createTargetChooser(string s, MTGCardInstance * card); + TargetChooser * createTargetChooser(string s, MTGCardInstance * card); TargetChooser * createTargetChooser(MTGCardInstance * card); }; class TargetZoneChooser:public TargetChooser{ -public: - MTGGameZone * zones[6]; - int nbzones; - int init(MTGGameZone ** _zones, int _nbzones); - TargetZoneChooser(MTGCardInstance * card = NULL, int _maxtargets = 1); - TargetZoneChooser(MTGGameZone ** _zones, int _nbzones, MTGCardInstance * card = NULL, int _maxtargets = 1); - virtual int canTarget(Targetable * _card); + public: + MTGGameZone * zones[6]; + int nbzones; + int init(MTGGameZone ** _zones, int _nbzones); + TargetZoneChooser(MTGCardInstance * card = NULL, int _maxtargets = 1); + TargetZoneChooser(MTGGameZone ** _zones, int _nbzones, MTGCardInstance * card = NULL, int _maxtargets = 1); + virtual int canTarget(Targetable * _card); }; class CreatureTargetChooser:public TargetZoneChooser{ -public: - int maxpower; - int maxtoughness; - CreatureTargetChooser(MTGGameZone ** _zones, int _nbzones,MTGCardInstance * card = NULL, int _maxtargets = 1); - CreatureTargetChooser(MTGCardInstance * card = NULL, int _maxtargets = 1); - virtual int canTarget(Targetable * _card); + public: + int maxpower; + int maxtoughness; + CreatureTargetChooser(MTGGameZone ** _zones, int _nbzones,MTGCardInstance * card = NULL, int _maxtargets = 1); + CreatureTargetChooser(MTGCardInstance * card = NULL, int _maxtargets = 1); + virtual int canTarget(Targetable * _card); }; class DamageableTargetChooser:public CreatureTargetChooser{ -public: - DamageableTargetChooser(MTGGameZone ** _zones, int _nbzones,MTGCardInstance * card = NULL, int _maxtargets = 1):CreatureTargetChooser( _zones,_nbzones, card, _maxtargets){}; - DamageableTargetChooser(MTGCardInstance * card = NULL, int _maxtargets = 1):CreatureTargetChooser(card, _maxtargets){}; - virtual int canTarget(Targetable * target); + public: + DamageableTargetChooser(MTGGameZone ** _zones, int _nbzones,MTGCardInstance * card = NULL, int _maxtargets = 1):CreatureTargetChooser( _zones,_nbzones, card, _maxtargets){}; + DamageableTargetChooser(MTGCardInstance * card = NULL, int _maxtargets = 1):CreatureTargetChooser(card, _maxtargets){}; + virtual int canTarget(Targetable * target); }; class PlayerTargetChooser:public TargetChooser{ -public: - PlayerTargetChooser(MTGCardInstance * card = NULL, int _maxtargets = 1):TargetChooser(card, _maxtargets){}; - virtual int canTarget(Targetable * target); + public: + PlayerTargetChooser(MTGCardInstance * card = NULL, int _maxtargets = 1):TargetChooser(card, _maxtargets){}; + virtual int canTarget(Targetable * target); }; class TypeTargetChooser:public TargetZoneChooser{ -public: - int nbtypes; - int types[10]; - TypeTargetChooser(const char * _type, MTGCardInstance * card = NULL, int _maxtargets = 1); - TypeTargetChooser(const char * _type, MTGGameZone ** _zones, int nbzones, MTGCardInstance * card = NULL, int _maxtargets = 1); - void addType(int type); - void addType(const char * type); - virtual int canTarget(Targetable * targe); + public: + int nbtypes; + int types[10]; + TypeTargetChooser(const char * _type, MTGCardInstance * card = NULL, int _maxtargets = 1); + TypeTargetChooser(const char * _type, MTGGameZone ** _zones, int nbzones, MTGCardInstance * card = NULL, int _maxtargets = 1); + void addType(int type); + void addType(const char * type); + virtual int canTarget(Targetable * targe); }; class DescriptorTargetChooser:public TargetZoneChooser{ -public: - CardDescriptor * cd; - DescriptorTargetChooser(CardDescriptor * _cd, MTGCardInstance * card = NULL, int _maxtargets = 1); - DescriptorTargetChooser(CardDescriptor * _cd, MTGGameZone ** _zones, int nbzones, MTGCardInstance * card = NULL, int _maxtargets = 1); - virtual int canTarget(Targetable * target); + public: + CardDescriptor * cd; + DescriptorTargetChooser(CardDescriptor * _cd, MTGCardInstance * card = NULL, int _maxtargets = 1); + DescriptorTargetChooser(CardDescriptor * _cd, MTGGameZone ** _zones, int nbzones, MTGCardInstance * card = NULL, int _maxtargets = 1); + virtual int canTarget(Targetable * target); }; class SpellTargetChooser:public TargetChooser{ -public: - int color; - SpellTargetChooser( MTGCardInstance * card = NULL,int _color = -1, int _maxtargets = 1 ); - virtual int canTarget(Targetable * target); + public: + int color; + SpellTargetChooser( MTGCardInstance * card = NULL,int _color = -1, int _maxtargets = 1 ); + virtual int canTarget(Targetable * target); }; class SpellOrPermanentTargetChooser:public TargetZoneChooser{ -public: - int color; - SpellOrPermanentTargetChooser(MTGCardInstance * card = NULL,int _color = -1 , int _maxtargets = 1); - virtual int canTarget(Targetable * target); + public: + int color; + SpellOrPermanentTargetChooser(MTGCardInstance * card = NULL,int _color = -1 , int _maxtargets = 1); + virtual int canTarget(Targetable * target); }; class DamageTargetChooser:public TargetChooser{ -public: - int color; - int state; - DamageTargetChooser( MTGCardInstance * card = NULL,int _color = -1 , int _maxtargets = 1, int state = NOT_RESOLVED); - virtual int canTarget(Targetable * target); + public: + int color; + int state; + DamageTargetChooser( MTGCardInstance * card = NULL,int _color = -1 , int _maxtargets = 1, int state = NOT_RESOLVED); + virtual int canTarget(Targetable * target); }; class DamageOrPermanentTargetChooser:public TargetZoneChooser{ -public: - int color; - DamageOrPermanentTargetChooser(MTGCardInstance * card = NULL,int _color = -1 , int _maxtargets = 1); - virtual int canTarget(Targetable * target); + public: + int color; + DamageOrPermanentTargetChooser(MTGCardInstance * card = NULL,int _color = -1 , int _maxtargets = 1); + virtual int canTarget(Targetable * target); }; #endif diff --git a/projects/mtg/include/Targetable.h b/projects/mtg/include/Targetable.h index b779c207b..1a2581f7a 100644 --- a/projects/mtg/include/Targetable.h +++ b/projects/mtg/include/Targetable.h @@ -1,13 +1,13 @@ -#ifndef _TARGETABLE_H_ -#define _TARGETABLE_H_ - -#define TARGET_CARD 1 -#define TARGET_PLAYER 2 -#define TARGET_STACKACTION 3 - -class Targetable{ -public: - virtual int typeAsTarget() = 0; -}; - -#endif \ No newline at end of file +#ifndef _TARGETABLE_H_ +#define _TARGETABLE_H_ + +#define TARGET_CARD 1 +#define TARGET_PLAYER 2 +#define TARGET_STACKACTION 3 + +class Targetable{ + public: + virtual int typeAsTarget() = 0; +}; + +#endif diff --git a/projects/mtg/include/TargetsList.h b/projects/mtg/include/TargetsList.h index ee76d486d..2059b76e2 100644 --- a/projects/mtg/include/TargetsList.h +++ b/projects/mtg/include/TargetsList.h @@ -1,34 +1,34 @@ -#ifndef _TARGETSLIST_H_ -#define _TARGETSLIST_H_ - -#define MAX_TARGETS 20 - -class Targetable; -class MTGCardInstance; -class Player; -class Damageable; -class Spell; -class Interruptible; -class Damage; - -class TargetsList{ -public: - int cursor; - TargetsList(); - TargetsList(Targetable * _targets[], int nbtargets); - Targetable* targets[MAX_TARGETS]; - int alreadyHasTarget(Targetable * target); - int removeTarget(Targetable * _card); - int toggleTarget(Targetable * _card); - virtual int addTarget(Targetable * _target); - MTGCardInstance * getNextCardTarget(MTGCardInstance * previous = 0); - Player * getNextPlayerTarget(Player * previous = 0); - Damageable * getNextDamageableTarget(Damageable * previous = 0); - Interruptible * getNextInterruptible(Interruptible * previous, int type); - Spell * getNextSpellTarget(Spell * previous = 0); - Damage * getNextDamageTarget(Damage * previous = 0); - Targetable * getNextTarget(Targetable * previous, int type); - void initTargets(){cursor = 0;}; -}; - -#endif \ No newline at end of file +#ifndef _TARGETSLIST_H_ +#define _TARGETSLIST_H_ + +#define MAX_TARGETS 20 + +class Targetable; +class MTGCardInstance; +class Player; +class Damageable; +class Spell; +class Interruptible; +class Damage; + +class TargetsList{ + public: + int cursor; + TargetsList(); + TargetsList(Targetable * _targets[], int nbtargets); + Targetable* targets[MAX_TARGETS]; + int alreadyHasTarget(Targetable * target); + int removeTarget(Targetable * _card); + int toggleTarget(Targetable * _card); + virtual int addTarget(Targetable * _target); + MTGCardInstance * getNextCardTarget(MTGCardInstance * previous = 0); + Player * getNextPlayerTarget(Player * previous = 0); + Damageable * getNextDamageableTarget(Damageable * previous = 0); + Interruptible * getNextInterruptible(Interruptible * previous, int type); + Spell * getNextSpellTarget(Spell * previous = 0); + Damage * getNextDamageTarget(Damage * previous = 0); + Targetable * getNextTarget(Targetable * previous, int type); + void initTargets(){cursor = 0;}; +}; + +#endif diff --git a/projects/mtg/include/TestSuiteAI.h b/projects/mtg/include/TestSuiteAI.h index f2926f878..4434922b3 100644 --- a/projects/mtg/include/TestSuiteAI.h +++ b/projects/mtg/include/TestSuiteAI.h @@ -1,85 +1,85 @@ -#ifndef _TESTSUITE_AI_H_ -#define _TESTSUITE_AI_H_ - -#define MAX_TESTSUITE_ACTIONS 100 -#define MAX_TESTUITE_CARDS 100 - -#include "../include/AIPlayer.h" - -class TestSuiteActions{ -public: - int nbitems; - string actions[MAX_TESTSUITE_ACTIONS]; - void add(string action); - TestSuiteActions(); - void cleanup(); -}; - -class TestSuitePlayerZone{ -public: - int cards[MAX_TESTUITE_CARDS]; - int nbitems; - void add(int cardid); - TestSuitePlayerZone(); - void cleanup(); -}; - -class TestSuitePlayerData{ -public: - int life; - ManaCost * manapool; - TestSuitePlayerZone zones[5]; - TestSuitePlayerData(); - ~TestSuitePlayerData(); - void cleanup(); - -}; - - - -class TestSuiteState{ -public: - int phase; - void parsePlayerState(int playerId, string s); - TestSuiteState(); - TestSuitePlayerData playerData[2]; - void cleanup(); -}; -class TestSuite{ -public: - float timerLimit; - int currentAction; - TestSuiteState initState; - TestSuiteState endState; - TestSuiteActions actions; - string files[128]; - int nbfiles; - int currentfile; - void load(const char * filename); - TestSuite(const char * filename); - void initGame(); - int assertGame(); - MTGPlayerCards * buildDeck(MTGAllCards * collection, int playerId); - string getNextAction(); - int phaseStrToInt(string s); - MTGCardInstance * getCardByMTGId(int mtgid); - Interruptible * getActionByMTGId(int mtgid); - int loadNext(); - void cleanup(); - int Log(const char * text); - -}; - -class TestSuiteAI:public AIPlayer{ -public: - TestSuite * suite; - float timer; - TestSuiteAI(MTGAllCards * collection,TestSuite * suite, int playerId); - virtual int Act(float dt); - virtual int displayStack(){return 1;} - -}; - - - -#endif \ No newline at end of file +#ifndef _TESTSUITE_AI_H_ +#define _TESTSUITE_AI_H_ + +#define MAX_TESTSUITE_ACTIONS 100 +#define MAX_TESTUITE_CARDS 100 + +#include "../include/AIPlayer.h" + +class TestSuiteActions{ + public: + int nbitems; + string actions[MAX_TESTSUITE_ACTIONS]; + void add(string action); + TestSuiteActions(); + void cleanup(); +}; + +class TestSuitePlayerZone{ + public: + int cards[MAX_TESTUITE_CARDS]; + int nbitems; + void add(int cardid); + TestSuitePlayerZone(); + void cleanup(); +}; + +class TestSuitePlayerData{ + public: + int life; + ManaCost * manapool; + TestSuitePlayerZone zones[5]; + TestSuitePlayerData(); + ~TestSuitePlayerData(); + void cleanup(); + +}; + + + +class TestSuiteState{ + public: + int phase; + void parsePlayerState(int playerId, string s); + TestSuiteState(); + TestSuitePlayerData playerData[2]; + void cleanup(); +}; +class TestSuite{ + public: + float timerLimit; + int currentAction; + TestSuiteState initState; + TestSuiteState endState; + TestSuiteActions actions; + string files[128]; + int nbfiles; + int currentfile; + void load(const char * filename); + TestSuite(const char * filename); + void initGame(); + int assertGame(); + MTGPlayerCards * buildDeck(MTGAllCards * collection, int playerId); + string getNextAction(); + int phaseStrToInt(string s); + MTGCardInstance * getCardByMTGId(int mtgid); + Interruptible * getActionByMTGId(int mtgid); + int loadNext(); + void cleanup(); + int Log(const char * text); + +}; + +class TestSuiteAI:public AIPlayer{ + public: + TestSuite * suite; + float timer; + TestSuiteAI(MTGAllCards * collection,TestSuite * suite, int playerId); + virtual int Act(float dt); + virtual int displayStack(){return 1;} + +}; + + + +#endif diff --git a/projects/mtg/include/TexturesCache.h b/projects/mtg/include/TexturesCache.h index b9e5ccb64..90a6b923a 100644 --- a/projects/mtg/include/TexturesCache.h +++ b/projects/mtg/include/TexturesCache.h @@ -22,9 +22,9 @@ class CardTexture{ JTexture* tex; JQuad* quad; public: - int lastTime; - int type; - int nbpixels; + int lastTime; + int type; + int nbpixels; int getId(); JQuad * getQuad(); @@ -39,18 +39,18 @@ class TexturesCache{ int lastTime; int nb_textures; int delete_previous; - int totalsize; + int totalsize; CardTexture * cache[MAX_CACHE_OBJECTS]; public: int isInCache(MTGCard * card, int type=CACHE_CARD); TexturesCache(); - ~TexturesCache(); - int getOldestQuad(); - void removeQuad(int id); - int cleanup(); + ~TexturesCache(); + int getOldestQuad(); + void removeQuad(int id); + int cleanup(); int getCacheById(int id, int type=CACHE_CARD); JQuad * getQuad(MTGCard * card, int type=CACHE_CARD); - JQuad * getThumb(MTGCard * card){return getQuad(card, CACHE_THUMB);}; + JQuad * getThumb(MTGCard * card){return getQuad(card, CACHE_THUMB);}; }; diff --git a/projects/mtg/include/debug.h b/projects/mtg/include/debug.h index 00031ffde..63bafe8f8 100644 --- a/projects/mtg/include/debug.h +++ b/projects/mtg/include/debug.h @@ -1,22 +1,22 @@ -#ifndef _DEBUG_H_ -#define _DEBUG_H_ - -#if defined (WIN32) || defined (LINUX) -#define TESTSUITE 1 -#endif - -#ifdef _DEBUG -#define NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) -#else -#define NEW new -#endif - -#ifdef LINUX - #ifdef _DEBUG - #define OutputDebugString(val) (std::cerr << val); - #else - #define OutputDebugString(val) {} - #endif -#endif - -#endif +#ifndef _DEBUG_H_ +#define _DEBUG_H_ + +#if defined (WIN32) || defined (LINUX) +#define TESTSUITE 1 +#endif + +#ifdef _DEBUG +#define NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) +#else +#define NEW new +#endif + +#ifdef LINUX +#ifdef _DEBUG +#define OutputDebugString(val) (std::cerr << val); +#else +#define OutputDebugString(val) {} +#endif +#endif + +#endif diff --git a/projects/mtg/include/utils.h b/projects/mtg/include/utils.h index 4c966217d..72e2185c1 100644 --- a/projects/mtg/include/utils.h +++ b/projects/mtg/include/utils.h @@ -1,50 +1,50 @@ -#ifndef _UTILS_H_ -#define _UTILS_H_ - -#include - -#if defined (WIN32) || defined (LINUX) - -#else -#include -#include -#include -#include -#include -#include -#include -#include - -#endif - - -#include -#include -#include -#include -#include -#include -#include - -#define BUFSIZE 600 - - - -using std::string; - -template -char ( &_ArraySizeHelper( T (&array)[N] ))[N]; -#define countof( array ) (sizeof( _ArraySizeHelper( array ) )) - - - -int lowercase(string source); - -int substr_copy(char *source, char *target, int start, int len); -int append_str(char * s1, char * s2, char * target); -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); - -#endif +#ifndef _UTILS_H_ +#define _UTILS_H_ + +#include + +#if defined (WIN32) || defined (LINUX) + +#else +#include +#include +#include +#include +#include +#include +#include +#include + +#endif + + +#include +#include +#include +#include +#include +#include +#include + +#define BUFSIZE 600 + + + +using std::string; + +template + char ( &_ArraySizeHelper( T (&array)[N] ))[N]; +#define countof( array ) (sizeof( _ArraySizeHelper( array ) )) + + + +int lowercase(string source); + +int substr_copy(char *source, char *target, int start, int len); +int append_str(char * s1, char * s2, char * target); +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); + +#endif diff --git a/projects/mtg/src/AIPlayer.cpp b/projects/mtg/src/AIPlayer.cpp index af9f87b72..f56822432 100644 --- a/projects/mtg/src/AIPlayer.cpp +++ b/projects/mtg/src/AIPlayer.cpp @@ -1,624 +1,624 @@ -#include "../include/debug.h" -#include "../include/AIPlayer.h" -#include "../include/CardDescriptor.h" -#include "../include/DamageResolverLayer.h" -#include "../include/DamagerDamaged.h" -#include "../include/AIStats.h" - -const char * const MTG_LAND_TEXTS[] = {"artifact","forest","island","mountain","swamp","plains","other lands"}; - -AIPlayer::AIPlayer(MTGPlayerCards * _deck, string file): Player(_deck, file){ - potentialMana = NEW ManaCost(); - nextCardToPlay = NULL; - stats = NULL; -} - -AIPlayer::~AIPlayer(){ - if (potentialMana) delete potentialMana; - SAFE_DELETE(stats); -} -MTGCardInstance * AIPlayer::chooseCard(TargetChooser * tc, MTGCardInstance * source, int random){ - for (int i = 0; i < game->hand->nb_cards; i++){ - MTGCardInstance * card = game->hand->cards[i]; - if (!tc->alreadyHasTarget(card) && tc->canTarget(card)){ - return card; - } - } - return NULL; -} - -int AIPlayer::Act(float dt){ - GameObserver * gameObs = GameObserver::GetInstance(); - if (gameObs->currentPlayer == this){ - gameObs->userRequestNextGamePhase(); - return 1; - }else{ - return 1; - } -} - - -void AIPlayer::tapLandsForMana(ManaCost * potentialMana, ManaCost * cost){ - #if defined (WIN32) || defined (LINUX) -OutputDebugString("tapping land for mana\n"); -#endif - - ManaCost * diff = potentialMana->Diff(cost); - int currentCost = 0; - GameObserver * gameObs = GameObserver::GetInstance(); - CardDescriptor cd; - cd.setColor(MTG_COLOR_LAND); - cd.tapped = -1; - - MTGCardInstance * card = NULL; - while((card = cd.nextmatch(game->inPlay, card))){ -#if defined (WIN32) || defined (LINUX) - OutputDebugString("Found mana card\n"); -#endif - int doTap = 1; - for (int i=MTG_NB_COLORS-1; i>= 0; i--){ - if (diff->getCost(i) && card->hasSubtype(MTG_LAND_TEXTS[i]) ){ -#if defined (WIN32) || defined (LINUX) - OutputDebugString("Not Gonna Tap\n"); -#endif - diff->remove(i,1); - doTap = 0; - break; - } - } - if (doTap){ - gameObs->cardClick(card); -#if defined (WIN32) || defined (LINUX) - OutputDebugString("Tapped\n"); -#endif - } - } - - delete(diff); - -/* - - for (int i=MTG_NB_COLORS-1; i>= 0; i--){ - #if defined (WIN32) || defined (LINUX) -char buf[4096]; -sprintf(buf,"Testing %s \n" ,MTG_LAND_TEXTS[i]); -OutputDebugString(buf); -#endif - currentCost = cost->getCost(i); - while(currentCost){ - #if defined (WIN32) || defined (LINUX) -sprintf(buf,"Cost for %s is %i \n" ,MTG_LAND_TEXTS[i], currentCost); -OutputDebugString(buf); -#endif - MTGCardInstance * card = NULL; - while(currentCost && (card = cd.nextmatch(game->inPlay, card))){ - if (i==MTG_COLOR_ARTIFACT || card->hasSubtype(MTG_LAND_TEXTS[i]) ){ - currentCost--; - gameObs->cardClick(card); - } - } - } - } - -*/ - #if defined (WIN32) || defined (LINUX) -OutputDebugString("ok land tapped"); -#endif -} -//TODO a better function that does not take into account only basic lands -ManaCost * AIPlayer::getPotentialMana(){ - SAFE_DELETE(potentialMana); - potentialMana = NEW ManaCost(); - CardDescriptor cd; - cd.setColor(MTG_COLOR_LAND); - cd.tapped = -1; - MTGCardInstance * card = NULL; - while((card = cd.nextmatch(game->inPlay, card))){ - - if (card->hasSubtype("plains")){ -#if defined (WIN32) || defined (LINUX) -OutputDebugString("Found Potential plain\n"); -#endif - potentialMana->add(MTG_COLOR_WHITE,1); - }else if(card->hasSubtype("swamp")){ -#if defined (WIN32) || defined (LINUX) -OutputDebugString("Found Potential swamp\n"); -#endif - potentialMana->add(MTG_COLOR_BLACK,1); - }else if(card->hasSubtype("forest")){ -#if defined (WIN32) || defined (LINUX) -OutputDebugString("Found Potential forestn\n"); -#endif - potentialMana->add(MTG_COLOR_GREEN,1); - }else if(card->hasSubtype("mountain")){ -#if defined (WIN32) || defined (LINUX) -OutputDebugString("Found Potential Mountain\n"); -#endif - potentialMana->add(MTG_COLOR_RED,1); - }else if(card->hasSubtype("island")){ - potentialMana->add(MTG_COLOR_BLUE,1); - }else{ -#if defined (WIN32) || defined (LINUX) -OutputDebugString("WTF ????\n"); -#endif - } - } - return potentialMana; -} - - -//Default AI does not interrupt -int AIPlayer::checkInterrupt(){ - GameObserver * gameObs = GameObserver::GetInstance(); - if (gameObs->mLayers->stackLayer()->askIfWishesToInterrupt == this){ - gameObs->mLayers->stackLayer()->cancelInterruptOffer(); - return 1; - } - return 0; -} - -int AIPlayer::effectBadOrGood(MTGCardInstance * card){ - int id = card->getMTGId(); - switch (id){ - default: - break; - } - AbilityFactory * af = NEW AbilityFactory(); - int autoGuess = af->magicText(id,NULL,card); - delete af; - if (autoGuess) return autoGuess; - return BAKA_EFFECT_BAD; -} - -int AIPlayer::chooseTarget(TargetChooser * tc){ - Targetable * potentialTargets[50]; - int nbtargets = 0; - GameObserver * gameObs = GameObserver::GetInstance(); - int checkOnly = 0; - if (tc){ - checkOnly = 1; - }else{ - tc = gameObs->getCurrentTargetChooser(); - } - if (!tc) return 0; - if (!(gameObs->currentlyActing() == this)) return 0; - Player * target = this; - int cardEffect = effectBadOrGood(tc->source); - if (cardEffect == BAKA_EFFECT_BAD){ - target = this->opponent(); - } - - - if (!tc->alreadyHasTarget(target) && tc->canTarget(target) && nbtargets < 50){ - for (int i = 0; i < 3; i++){ //Increase probability to target a player when this is possible - potentialTargets[nbtargets] = target; - nbtargets++; - } - if (checkOnly) return 1; - } - MTGPlayerCards * playerZones = target->game; - MTGGameZone * zones[] = {playerZones->hand,playerZones->library,playerZones->inPlay, playerZones->graveyard}; - for (int j = 0; j < 4; j++){ - MTGGameZone * zone = zones[j]; - for (int k=0; k< zone->nb_cards; k++){ - MTGCardInstance * card = zone->cards[k]; - if (!tc->alreadyHasTarget(card) && tc->canTarget(card) && nbtargets < 50){ - if (checkOnly) return 1; - int multiplier = 1; - if (getStats() && getStats()->isInTop(card,10)){ - multiplier++; - if (getStats()->isInTop(card,5)){ - multiplier++; - if (getStats()->isInTop(card,3)){ - multiplier++; - } - } - } - for (int l=0; l < multiplier; l++){ - potentialTargets[nbtargets] = card; - nbtargets++; - } - } - } - } - if (nbtargets){ - int i = rand() % nbtargets; - int type = potentialTargets[i]->typeAsTarget(); - switch(type){ - case TARGET_CARD: - { - MTGCardInstance * card = ((MTGCardInstance *) potentialTargets[i]); - gameObs->cardClick(card); - return 1; - break; - } - case TARGET_PLAYER: - { - Player * player = ((Player *) potentialTargets[i]); - gameObs->cardClick(NULL, player); - return 1; - break; - } - } - } - //BIG PROBLEM - gameObs->cancelCurrentAction(); - return 0; -} - -int AIPlayer::getCreaturesInfo(Player * player, int neededInfo , int untapMode, int canAttack){ - int result = 0; - CardDescriptor cd; - cd.init(); - cd.setType("Creature"); - cd.tapped = untapMode; - MTGCardInstance * card = NULL; - while((card = cd.nextmatch(player->game->inPlay, card))){ - if (!canAttack || card->canAttack()){ - if (neededInfo == INFO_NBCREATURES){ - result++; - }else{ - result+=card->power; - } - } - } - return result; -} - - - -int AIPlayer::chooseAttackers(){ -//Attack with all creatures - //How much damage can the other player do during his next Attack ? - int opponentForce = getCreaturesInfo(opponent(),INFO_CREATURESPOWER); - int opponentCreatures = getCreaturesInfo(opponent(), INFO_NBCREATURES); - int myForce = getCreaturesInfo(this,INFO_CREATURESPOWER,-1,1); - int myCreatures = getCreaturesInfo(this, INFO_NBCREATURES, -1,1); - bool attack = (myCreatures > opponentCreatures || myForce > opponentForce || myForce > 2*opponent()->life); - if (attack){ - CardDescriptor cd; - cd.init(); - cd.setType("Creature"); - MTGCardInstance * card = NULL; - while((card = cd.nextmatch(game->inPlay, card))){ - GameObserver::GetInstance()->cardClick(card); - } - } - return 1; -} - -int AIPlayer::chooseBlockers(){ - map opponentsToughness; - int opponentForce = getCreaturesInfo(opponent(),INFO_CREATURESPOWER); - int opponentCreatures = getCreaturesInfo(opponent(), INFO_NBCREATURES, -1); - int myForce = getCreaturesInfo(this,INFO_CREATURESPOWER); - int myCreatures = getCreaturesInfo(this, INFO_NBCREATURES, -1); - CardDescriptor cd; - cd.init(); - cd.setType("Creature"); - cd.tapped = -1; - MTGCardInstance * card = NULL; - while((card = cd.nextmatch(game->inPlay, card))){ - GameObserver::GetInstance()->cardClick(card); - int set = 0; - while(!set){ - if (!card->defenser){ - set = 1; - }else{ - MTGCardInstance * attacker = card->defenser; - map::iterator it = opponentsToughness.find(attacker); - if ( it == opponentsToughness.end()){ - opponentsToughness[attacker] = attacker->toughness; - it = opponentsToughness.find(attacker); - } - if (opponentsToughness[attacker] > 0 && getStats() && getStats()->isInTop(attacker,3,false)){ - opponentsToughness[attacker]-= card->power; - set = 1; - }else{ - GameObserver::GetInstance()->cardClick(card); - } - } - } - } - card = NULL; - while((card = cd.nextmatch(game->inPlay, card))){ - if (card->defenser && opponentsToughness[card->defenser] > 0){ - while (card->defenser) GameObserver::GetInstance()->cardClick(card); - } - } - card = NULL; - while((card = cd.nextmatch(game->inPlay, card))){ - if(!card->defenser){ - GameObserver::GetInstance()->cardClick(card); - int set = 0; - while(!set){ - if (!card->defenser){ - set = 1; - }else{ - MTGCardInstance * attacker = card->defenser; - if (opponentsToughness[attacker] <= 0 || (card->toughness <= card->defenser->power && opponentForce*2 defenser->nbOpponents()>1){ - GameObserver::GetInstance()->cardClick(card); - }else{ - set = 1; - } - } - } - } - } - return 1; -} - -int AIPlayer::combatDamages(){ - int result = 0; - GameObserver * gameObs = GameObserver::GetInstance(); - Player * currentPlayer = gameObs->currentPlayer; - int currentGamePhase = gameObs->getCurrentGamePhase(); - if (currentGamePhase != MTG_PHASE_COMBATDAMAGE) return 0; - DamageResolverLayer * drl = gameObs->mLayers->combatLayer(); - #if defined (WIN32) || defined (LINUX) -OutputDebugString("AI Combat Phase START\n"); -#endif - if (drl->currentChoosingPlayer == this){ - #if defined (WIN32) || defined (LINUX) -OutputDebugString("This player chooses\n"); -#endif - for (int i = 0; i < drl->mCount; i++){ - #if defined (WIN32) || defined (LINUX) -OutputDebugString("AI Combat Phase\n"); -#endif - DamagerDamaged * current = (DamagerDamaged *) drl->mObjects[i]; - if (current->damageSelecter == this){ - result = 1; - DamagerDamaged * canardEmissaire = NULL; - for (int j = 0; j < drl->mCount; j++){ - DamagerDamaged * opponent = (DamagerDamaged *) drl->mObjects[j]; - if (drl->isOpponent(current, opponent)){ - if (!canardEmissaire) canardEmissaire = opponent; - int over = opponent->hasLethalDamage(); - while(!over){ - if(!current->dealOneDamage(opponent)){ - over = 1; - }else{ - over = opponent->hasLethalDamage(); - } - #if defined (WIN32) || defined (LINUX) - char buf[4096]; - sprintf(buf, "==========\n%s deals %i damages to %s\n=============\n", current->card->getName(), 1, opponent->card->getName()); -OutputDebugString(buf); -#endif - } - } - } - if (canardEmissaire && !current->card->has(TRAMPLE)){ - while(current->dealOneDamage(canardEmissaire)){ - #if defined (WIN32) || defined (LINUX) -OutputDebugString("==========\nDealing damage to Canard Emissaire\n================\n"); -#endif - - } - } - } - } - if (result){ - drl->nextPlayer(); - } - } - return result; - -} - -AIStats * AIPlayer::getStats(){ - if (!stats){ - char statFile[512]; - sprintf(statFile, "Res/ai/baka/stats/%s.stats", opponent()->deckFile.c_str()); - stats = new AIStats(this, statFile); - } - 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++; - } - } - if (!nbdecks) return NULL; - int deckid = 1 + rand() % (nbdecks); - char deckFile[512]; - sprintf(deckFile, "Res/ai/baka/deck%i.txt",deckid); - char deckFileSmall[512]; - sprintf(deckFileSmall, "ai_baka_deck%i",deckid); -#if defined (WIN32) || defined (LINUX) - char debuf[4096]; - sprintf(debuf,"Deck File: %s", deckFile); - OutputDebugString(debuf); -#endif - 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); - return baka; -} - - -MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * potentialMana, const char * type){ - int maxCost = -1; - MTGCardInstance * nextCardToPlay = NULL; - MTGCardInstance * card = NULL; - CardDescriptor cd; - cd.init(); - cd.setType(type); - card = NULL; - while((card = cd.nextmatch(game->hand, card))){ - int currentCost = card->getManaCost()->getConvertedCost(); - if (currentCost > maxCost && potentialMana->canAfford(card->getManaCost())){ - TargetChooserFactory * tcf = NEW TargetChooserFactory(); - TargetChooser * tc = tcf->createTargetChooser(card); - delete tcf; - if (tc){ - int hasTarget = (chooseTarget(tc)); - delete tc; - if (!hasTarget)continue; - } - nextCardToPlay = card; - maxCost = currentCost; - } - } - return nextCardToPlay; -} - -AIPlayerBaka::AIPlayerBaka(MTGPlayerCards * _deck, char * file): AIPlayer(_deck,file){ - mAvatarTex = JRenderer::GetInstance()->LoadTexture("ai/baka/avatar.jpg", TEX_TYPE_USE_VRAM); - if (mAvatarTex) - mAvatar = NEW JQuad(mAvatarTex, 0, 0, 35, 50); - initTimer(); -} - -void AIPlayerBaka::initTimer(){ - timer = 20; -} - -int AIPlayerBaka::Act(float dt){ - GameObserver * gameObs = GameObserver::GetInstance(); - int currentGamePhase = gameObs->getCurrentGamePhase(); - - if (currentGamePhase == MTG_PHASE_CLEANUP && currentGamePhase != oldGamePhase){ -#if defined (WIN32) || defined (LINUX) - OutputDebugString("updating stats\n"); -#endif - if (getStats()) getStats()->updateStats(); - } - - - oldGamePhase = currentGamePhase; - - if (checkInterrupt()) return 0; - - timer--; - if (timer>0){ - return 0; - } - initTimer(); - #if defined (WIN32) || defined (LINUX) -OutputDebugString("==========\nNew Act CALL\n================\n"); -#endif - - - - - #if defined (WIN32) || defined (LINUX) -OutputDebugString("==========\nCombat Damages ?\n================\n"); -#endif - if (combatDamages()) return 0; - - #if defined (WIN32) || defined (LINUX) -OutputDebugString("==========\nChoose Target ?\n================\n"); -#endif - if (chooseTarget()) return 0; - - - Player * currentPlayer = gameObs->currentPlayer; - - - - - CardDescriptor cd; - - - if (currentPlayer == this){ - MTGCardInstance * card = NULL; - switch(currentGamePhase){ - case MTG_PHASE_FIRSTMAIN: - case MTG_PHASE_SECONDMAIN: - if (canPutLandsIntoPlay){ - - //Attempt to put land into play - cd.init(); - cd.setColor(MTG_COLOR_LAND); - card = cd.match(game->hand); - if (card){ - gameObs->cardClick(card); - } - } - if(NULL == card){ - - //Attempt to put creature into play - if (manaPool->getConvertedCost()==0){ - - //No mana, try to get some - getPotentialMana(); - #if defined (WIN32) || defined (LINUX) - char buffe[4096]; - -sprintf(buffe,"potentail mana %i\n",potentialMana->getConvertedCost() ); -OutputDebugString(buffe); -#endif - if (potentialMana->getConvertedCost() > 0){ - - - //look for the most expensive creature we can afford - nextCardToPlay = FindCardToPlay(potentialMana, "creature"); - //Let's Try an enchantment maybe ? - if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(potentialMana, "enchantment"); - if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(potentialMana, "artifact"); - if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(potentialMana, "instant"); - if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(potentialMana, "sorcery"); - if (nextCardToPlay){ -#if defined (WIN32) || defined (LINUX) - sprintf(buffe, "Putting Card Into Play: %s", nextCardToPlay->getName()); - OutputDebugString(buffe); -#endif - - tapLandsForMana(potentialMana,nextCardToPlay->getManaCost()); - } - } - SAFE_DELETE(potentialMana); - }else{ - //We have mana, we can try to put the card into play - #if defined (WIN32) || defined (LINUX) -OutputDebugString("Mana paid, ready to put card into play\n"); -#endif - if (nextCardToPlay){ - gameObs->cardClick(nextCardToPlay); - nextCardToPlay = NULL; - }else{ - //ERROR, WE PAID MANA WITHOUT ANY WILL TO PLAY - } - } - } - if (NULL == card && NULL == nextCardToPlay){ - #if defined (WIN32) || defined (LINUX) -OutputDebugString("Switching to next phase\n"); -#endif - gameObs->userRequestNextGamePhase(); - } - break; - case MTG_PHASE_COMBATATTACKERS: - chooseAttackers(); - gameObs->userRequestNextGamePhase(); - break; - default: - gameObs->userRequestNextGamePhase(); - break; - } - }else{ - switch(currentGamePhase){ - case MTG_PHASE_COMBATBLOCKERS: - chooseBlockers(); - gameObs->userRequestNextGamePhase(); - break; - default: - break; - } - return 1; - } - return 1; -} +#include "../include/debug.h" +#include "../include/AIPlayer.h" +#include "../include/CardDescriptor.h" +#include "../include/DamageResolverLayer.h" +#include "../include/DamagerDamaged.h" +#include "../include/AIStats.h" + +const char * const MTG_LAND_TEXTS[] = {"artifact","forest","island","mountain","swamp","plains","other lands"}; + +AIPlayer::AIPlayer(MTGPlayerCards * _deck, string file): Player(_deck, file){ + potentialMana = NEW ManaCost(); + nextCardToPlay = NULL; + stats = NULL; +} + +AIPlayer::~AIPlayer(){ + if (potentialMana) delete potentialMana; + SAFE_DELETE(stats); +} +MTGCardInstance * AIPlayer::chooseCard(TargetChooser * tc, MTGCardInstance * source, int random){ + for (int i = 0; i < game->hand->nb_cards; i++){ + MTGCardInstance * card = game->hand->cards[i]; + if (!tc->alreadyHasTarget(card) && tc->canTarget(card)){ + return card; + } + } + return NULL; +} + +int AIPlayer::Act(float dt){ + GameObserver * gameObs = GameObserver::GetInstance(); + if (gameObs->currentPlayer == this){ + gameObs->userRequestNextGamePhase(); + return 1; + }else{ + return 1; + } +} + + +void AIPlayer::tapLandsForMana(ManaCost * potentialMana, ManaCost * cost){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("tapping land for mana\n"); +#endif + + ManaCost * diff = potentialMana->Diff(cost); + int currentCost = 0; + GameObserver * gameObs = GameObserver::GetInstance(); + CardDescriptor cd; + cd.setColor(MTG_COLOR_LAND); + cd.tapped = -1; + + MTGCardInstance * card = NULL; + while((card = cd.nextmatch(game->inPlay, card))){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("Found mana card\n"); +#endif + int doTap = 1; + for (int i=MTG_NB_COLORS-1; i>= 0; i--){ + if (diff->getCost(i) && card->hasSubtype(MTG_LAND_TEXTS[i]) ){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("Not Gonna Tap\n"); +#endif + diff->remove(i,1); + doTap = 0; + break; + } + } + if (doTap){ + gameObs->cardClick(card); +#if defined (WIN32) || defined (LINUX) + OutputDebugString("Tapped\n"); +#endif + } + } + + delete(diff); + + /* + + for (int i=MTG_NB_COLORS-1; i>= 0; i--){ + #if defined (WIN32) || defined (LINUX) + char buf[4096]; + sprintf(buf,"Testing %s \n" ,MTG_LAND_TEXTS[i]); + OutputDebugString(buf); + #endif + currentCost = cost->getCost(i); + while(currentCost){ + #if defined (WIN32) || defined (LINUX) + sprintf(buf,"Cost for %s is %i \n" ,MTG_LAND_TEXTS[i], currentCost); + OutputDebugString(buf); + #endif + MTGCardInstance * card = NULL; + while(currentCost && (card = cd.nextmatch(game->inPlay, card))){ + if (i==MTG_COLOR_ARTIFACT || card->hasSubtype(MTG_LAND_TEXTS[i]) ){ + currentCost--; + gameObs->cardClick(card); + } + } + } + } + + */ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("ok land tapped"); +#endif +} +//TODO a better function that does not take into account only basic lands +ManaCost * AIPlayer::getPotentialMana(){ + SAFE_DELETE(potentialMana); + potentialMana = NEW ManaCost(); + CardDescriptor cd; + cd.setColor(MTG_COLOR_LAND); + cd.tapped = -1; + MTGCardInstance * card = NULL; + while((card = cd.nextmatch(game->inPlay, card))){ + + if (card->hasSubtype("plains")){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("Found Potential plain\n"); +#endif + potentialMana->add(MTG_COLOR_WHITE,1); + }else if(card->hasSubtype("swamp")){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("Found Potential swamp\n"); +#endif + potentialMana->add(MTG_COLOR_BLACK,1); + }else if(card->hasSubtype("forest")){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("Found Potential forestn\n"); +#endif + potentialMana->add(MTG_COLOR_GREEN,1); + }else if(card->hasSubtype("mountain")){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("Found Potential Mountain\n"); +#endif + potentialMana->add(MTG_COLOR_RED,1); + }else if(card->hasSubtype("island")){ + potentialMana->add(MTG_COLOR_BLUE,1); + }else{ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("WTF ????\n"); +#endif + } + } + return potentialMana; +} + + +//Default AI does not interrupt +int AIPlayer::checkInterrupt(){ + GameObserver * gameObs = GameObserver::GetInstance(); + if (gameObs->mLayers->stackLayer()->askIfWishesToInterrupt == this){ + gameObs->mLayers->stackLayer()->cancelInterruptOffer(); + return 1; + } + return 0; +} + +int AIPlayer::effectBadOrGood(MTGCardInstance * card){ + int id = card->getMTGId(); + switch (id){ + default: + break; + } + AbilityFactory * af = NEW AbilityFactory(); + int autoGuess = af->magicText(id,NULL,card); + delete af; + if (autoGuess) return autoGuess; + return BAKA_EFFECT_BAD; +} + +int AIPlayer::chooseTarget(TargetChooser * tc){ + Targetable * potentialTargets[50]; + int nbtargets = 0; + GameObserver * gameObs = GameObserver::GetInstance(); + int checkOnly = 0; + if (tc){ + checkOnly = 1; + }else{ + tc = gameObs->getCurrentTargetChooser(); + } + if (!tc) return 0; + if (!(gameObs->currentlyActing() == this)) return 0; + Player * target = this; + int cardEffect = effectBadOrGood(tc->source); + if (cardEffect == BAKA_EFFECT_BAD){ + target = this->opponent(); + } + + + if (!tc->alreadyHasTarget(target) && tc->canTarget(target) && nbtargets < 50){ + for (int i = 0; i < 3; i++){ //Increase probability to target a player when this is possible + potentialTargets[nbtargets] = target; + nbtargets++; + } + if (checkOnly) return 1; + } + MTGPlayerCards * playerZones = target->game; + MTGGameZone * zones[] = {playerZones->hand,playerZones->library,playerZones->inPlay, playerZones->graveyard}; + for (int j = 0; j < 4; j++){ + MTGGameZone * zone = zones[j]; + for (int k=0; k< zone->nb_cards; k++){ + MTGCardInstance * card = zone->cards[k]; + if (!tc->alreadyHasTarget(card) && tc->canTarget(card) && nbtargets < 50){ + if (checkOnly) return 1; + int multiplier = 1; + if (getStats() && getStats()->isInTop(card,10)){ + multiplier++; + if (getStats()->isInTop(card,5)){ + multiplier++; + if (getStats()->isInTop(card,3)){ + multiplier++; + } + } + } + for (int l=0; l < multiplier; l++){ + potentialTargets[nbtargets] = card; + nbtargets++; + } + } + } + } + if (nbtargets){ + int i = rand() % nbtargets; + int type = potentialTargets[i]->typeAsTarget(); + switch(type){ + case TARGET_CARD: + { + MTGCardInstance * card = ((MTGCardInstance *) potentialTargets[i]); + gameObs->cardClick(card); + return 1; + break; + } + case TARGET_PLAYER: + { + Player * player = ((Player *) potentialTargets[i]); + gameObs->cardClick(NULL, player); + return 1; + break; + } + } + } + //BIG PROBLEM + gameObs->cancelCurrentAction(); + return 0; +} + +int AIPlayer::getCreaturesInfo(Player * player, int neededInfo , int untapMode, int canAttack){ + int result = 0; + CardDescriptor cd; + cd.init(); + cd.setType("Creature"); + cd.tapped = untapMode; + MTGCardInstance * card = NULL; + while((card = cd.nextmatch(player->game->inPlay, card))){ + if (!canAttack || card->canAttack()){ + if (neededInfo == INFO_NBCREATURES){ + result++; + }else{ + result+=card->power; + } + } + } + return result; +} + + + +int AIPlayer::chooseAttackers(){ + //Attack with all creatures + //How much damage can the other player do during his next Attack ? + int opponentForce = getCreaturesInfo(opponent(),INFO_CREATURESPOWER); + int opponentCreatures = getCreaturesInfo(opponent(), INFO_NBCREATURES); + int myForce = getCreaturesInfo(this,INFO_CREATURESPOWER,-1,1); + int myCreatures = getCreaturesInfo(this, INFO_NBCREATURES, -1,1); + bool attack = (myCreatures > opponentCreatures || myForce > opponentForce || myForce > 2*opponent()->life); + if (attack){ + CardDescriptor cd; + cd.init(); + cd.setType("Creature"); + MTGCardInstance * card = NULL; + while((card = cd.nextmatch(game->inPlay, card))){ + GameObserver::GetInstance()->cardClick(card); + } + } + return 1; +} + +int AIPlayer::chooseBlockers(){ + map opponentsToughness; + int opponentForce = getCreaturesInfo(opponent(),INFO_CREATURESPOWER); + int opponentCreatures = getCreaturesInfo(opponent(), INFO_NBCREATURES, -1); + int myForce = getCreaturesInfo(this,INFO_CREATURESPOWER); + int myCreatures = getCreaturesInfo(this, INFO_NBCREATURES, -1); + CardDescriptor cd; + cd.init(); + cd.setType("Creature"); + cd.tapped = -1; + MTGCardInstance * card = NULL; + while((card = cd.nextmatch(game->inPlay, card))){ + GameObserver::GetInstance()->cardClick(card); + int set = 0; + while(!set){ + if (!card->defenser){ + set = 1; + }else{ + MTGCardInstance * attacker = card->defenser; + map::iterator it = opponentsToughness.find(attacker); + if ( it == opponentsToughness.end()){ + opponentsToughness[attacker] = attacker->toughness; + it = opponentsToughness.find(attacker); + } + if (opponentsToughness[attacker] > 0 && getStats() && getStats()->isInTop(attacker,3,false)){ + opponentsToughness[attacker]-= card->power; + set = 1; + }else{ + GameObserver::GetInstance()->cardClick(card); + } + } + } + } + card = NULL; + while((card = cd.nextmatch(game->inPlay, card))){ + if (card->defenser && opponentsToughness[card->defenser] > 0){ + while (card->defenser) GameObserver::GetInstance()->cardClick(card); + } + } + card = NULL; + while((card = cd.nextmatch(game->inPlay, card))){ + if(!card->defenser){ + GameObserver::GetInstance()->cardClick(card); + int set = 0; + while(!set){ + if (!card->defenser){ + set = 1; + }else{ + MTGCardInstance * attacker = card->defenser; + if (opponentsToughness[attacker] <= 0 || (card->toughness <= card->defenser->power && opponentForce*2 defenser->nbOpponents()>1){ + GameObserver::GetInstance()->cardClick(card); + }else{ + set = 1; + } + } + } + } + } + return 1; +} + +int AIPlayer::combatDamages(){ + int result = 0; + GameObserver * gameObs = GameObserver::GetInstance(); + Player * currentPlayer = gameObs->currentPlayer; + int currentGamePhase = gameObs->getCurrentGamePhase(); + if (currentGamePhase != MTG_PHASE_COMBATDAMAGE) return 0; + DamageResolverLayer * drl = gameObs->mLayers->combatLayer(); +#if defined (WIN32) || defined (LINUX) + OutputDebugString("AI Combat Phase START\n"); +#endif + if (drl->currentChoosingPlayer == this){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("This player chooses\n"); +#endif + for (int i = 0; i < drl->mCount; i++){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("AI Combat Phase\n"); +#endif + DamagerDamaged * current = (DamagerDamaged *) drl->mObjects[i]; + if (current->damageSelecter == this){ + result = 1; + DamagerDamaged * canardEmissaire = NULL; + for (int j = 0; j < drl->mCount; j++){ + DamagerDamaged * opponent = (DamagerDamaged *) drl->mObjects[j]; + if (drl->isOpponent(current, opponent)){ + if (!canardEmissaire) canardEmissaire = opponent; + int over = opponent->hasLethalDamage(); + while(!over){ + if(!current->dealOneDamage(opponent)){ + over = 1; + }else{ + over = opponent->hasLethalDamage(); + } +#if defined (WIN32) || defined (LINUX) + char buf[4096]; + sprintf(buf, "==========\n%s deals %i damages to %s\n=============\n", current->card->getName(), 1, opponent->card->getName()); + OutputDebugString(buf); +#endif + } + } + } + if (canardEmissaire && !current->card->has(TRAMPLE)){ + while(current->dealOneDamage(canardEmissaire)){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("==========\nDealing damage to Canard Emissaire\n================\n"); +#endif + + } + } + } + } + if (result){ + drl->nextPlayer(); + } + } + return result; + +} + +AIStats * AIPlayer::getStats(){ + if (!stats){ + char statFile[512]; + sprintf(statFile, "Res/ai/baka/stats/%s.stats", opponent()->deckFile.c_str()); + stats = new AIStats(this, statFile); + } + 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++; + } + } + if (!nbdecks) return NULL; + int deckid = 1 + rand() % (nbdecks); + char deckFile[512]; + sprintf(deckFile, "Res/ai/baka/deck%i.txt",deckid); + char deckFileSmall[512]; + sprintf(deckFileSmall, "ai_baka_deck%i",deckid); +#if defined (WIN32) || defined (LINUX) + char debuf[4096]; + sprintf(debuf,"Deck File: %s", deckFile); + OutputDebugString(debuf); +#endif + 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); + return baka; +} + + +MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * potentialMana, const char * type){ + int maxCost = -1; + MTGCardInstance * nextCardToPlay = NULL; + MTGCardInstance * card = NULL; + CardDescriptor cd; + cd.init(); + cd.setType(type); + card = NULL; + while((card = cd.nextmatch(game->hand, card))){ + int currentCost = card->getManaCost()->getConvertedCost(); + if (currentCost > maxCost && potentialMana->canAfford(card->getManaCost())){ + TargetChooserFactory * tcf = NEW TargetChooserFactory(); + TargetChooser * tc = tcf->createTargetChooser(card); + delete tcf; + if (tc){ + int hasTarget = (chooseTarget(tc)); + delete tc; + if (!hasTarget)continue; + } + nextCardToPlay = card; + maxCost = currentCost; + } + } + return nextCardToPlay; +} + +AIPlayerBaka::AIPlayerBaka(MTGPlayerCards * _deck, char * file): AIPlayer(_deck,file){ + mAvatarTex = JRenderer::GetInstance()->LoadTexture("ai/baka/avatar.jpg", TEX_TYPE_USE_VRAM); + if (mAvatarTex) + mAvatar = NEW JQuad(mAvatarTex, 0, 0, 35, 50); + initTimer(); +} + +void AIPlayerBaka::initTimer(){ + timer = 20; +} + +int AIPlayerBaka::Act(float dt){ + GameObserver * gameObs = GameObserver::GetInstance(); + int currentGamePhase = gameObs->getCurrentGamePhase(); + + if (currentGamePhase == MTG_PHASE_CLEANUP && currentGamePhase != oldGamePhase){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("updating stats\n"); +#endif + if (getStats()) getStats()->updateStats(); + } + + + oldGamePhase = currentGamePhase; + + if (checkInterrupt()) return 0; + + timer--; + if (timer>0){ + return 0; + } + initTimer(); +#if defined (WIN32) || defined (LINUX) + OutputDebugString("==========\nNew Act CALL\n================\n"); +#endif + + + + +#if defined (WIN32) || defined (LINUX) + OutputDebugString("==========\nCombat Damages ?\n================\n"); +#endif + if (combatDamages()) return 0; + +#if defined (WIN32) || defined (LINUX) + OutputDebugString("==========\nChoose Target ?\n================\n"); +#endif + if (chooseTarget()) return 0; + + + Player * currentPlayer = gameObs->currentPlayer; + + + + + CardDescriptor cd; + + + if (currentPlayer == this){ + MTGCardInstance * card = NULL; + switch(currentGamePhase){ + case MTG_PHASE_FIRSTMAIN: + case MTG_PHASE_SECONDMAIN: + if (canPutLandsIntoPlay){ + + //Attempt to put land into play + cd.init(); + cd.setColor(MTG_COLOR_LAND); + card = cd.match(game->hand); + if (card){ + gameObs->cardClick(card); + } + } + if(NULL == card){ + + //Attempt to put creature into play + if (manaPool->getConvertedCost()==0){ + + //No mana, try to get some + getPotentialMana(); +#if defined (WIN32) || defined (LINUX) + char buffe[4096]; + + sprintf(buffe,"potentail mana %i\n",potentialMana->getConvertedCost() ); + OutputDebugString(buffe); +#endif + if (potentialMana->getConvertedCost() > 0){ + + + //look for the most expensive creature we can afford + nextCardToPlay = FindCardToPlay(potentialMana, "creature"); + //Let's Try an enchantment maybe ? + if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(potentialMana, "enchantment"); + if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(potentialMana, "artifact"); + if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(potentialMana, "instant"); + if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(potentialMana, "sorcery"); + if (nextCardToPlay){ +#if defined (WIN32) || defined (LINUX) + sprintf(buffe, "Putting Card Into Play: %s", nextCardToPlay->getName()); + OutputDebugString(buffe); +#endif + + tapLandsForMana(potentialMana,nextCardToPlay->getManaCost()); + } + } + SAFE_DELETE(potentialMana); + }else{ + //We have mana, we can try to put the card into play +#if defined (WIN32) || defined (LINUX) + OutputDebugString("Mana paid, ready to put card into play\n"); +#endif + if (nextCardToPlay){ + gameObs->cardClick(nextCardToPlay); + nextCardToPlay = NULL; + }else{ + //ERROR, WE PAID MANA WITHOUT ANY WILL TO PLAY + } + } + } + if (NULL == card && NULL == nextCardToPlay){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("Switching to next phase\n"); +#endif + gameObs->userRequestNextGamePhase(); + } + break; + case MTG_PHASE_COMBATATTACKERS: + chooseAttackers(); + gameObs->userRequestNextGamePhase(); + break; + default: + gameObs->userRequestNextGamePhase(); + break; + } + }else{ + switch(currentGamePhase){ + case MTG_PHASE_COMBATBLOCKERS: + chooseBlockers(); + gameObs->userRequestNextGamePhase(); + break; + default: + break; + } + return 1; + } + return 1; +} diff --git a/projects/mtg/src/AIStats.cpp b/projects/mtg/src/AIStats.cpp index 69c22c259..16589ddc4 100644 --- a/projects/mtg/src/AIStats.cpp +++ b/projects/mtg/src/AIStats.cpp @@ -1,129 +1,129 @@ -#include "../include/debug.h" -#include "../include/AIStats.h" -#include "../include/GameObserver.h" -#include "../include/Player.h" -#include "../include/MTGCardInstance.h" - -bool compare_aistats(AIStat * first, AIStat * second){ - float damage1 = first->value / first->occurences; - float damage2 = second->value/ second->occurences; - return (damage1 > damage2); -} - -AIStats::AIStats(Player * _player, char * _filename){ - filename = _filename; - load(_filename); - player = _player; -} - -AIStats::~AIStats(){ - list::iterator it; - for ( it=stats.begin() ; it != stats.end(); it++ ){ - AIStat * stat = *it; - delete stat; - } -} - -void AIStats::updateStatsCard(MTGCardInstance * cardInstance, Damage * damage, float multiplier){ - MTGCard * card = cardInstance->model; - AIStat * stat = find(card); - if (!stat){ - stat = NEW AIStat(card->getMTGId(),0,1,0); - stats.push_back(stat); - } - if (damage->target == player){ - stat->value+= multiplier * STATS_PLAYER_MULTIPLIER * damage->damage; - }else if (damage->target->type_as_damageable == DAMAGEABLE_MTGCARDINSTANCE){ - MTGCardInstance * target = (MTGCardInstance *)damage->target; - if (target->controller() == player && !target->isInPlay()){ - //One of my creatures got lethal damage... - stat->value+= multiplier * STATS_CREATURE_MULTIPLIER * damage->damage; - } - } -} - -void AIStats::updateStats(){ - GameObserver * game = GameObserver::GetInstance(); - ActionStack * as = game->mLayers->stackLayer(); - Damage * damage = ((Damage * )as->getNext(NULL,ACTION_DAMAGE, RESOLVED_OK)); - MTGGameZone * opponentZone = player->opponent()->game->inPlay; - while(damage){ - MTGCardInstance * card = damage->source; - updateStatsCard(card,damage); - - //Auras on damage source can be the cause - for (int i=0; i < opponentZone->nb_cards; i++){ - MTGCardInstance * aura = opponentZone->cards[i]; - if (aura->target == card){ - updateStatsCard(aura,damage, STATS_AURA_MULTIPLIER); - } - } - damage = ((Damage * )as->getNext(damage,ACTION_DAMAGE, RESOLVED_OK)); - } - stats.sort(compare_aistats); - save(); -} - -bool AIStats::isInTop(MTGCardInstance * card, unsigned int max, bool tooSmallCountsForTrue ){ - if (stats.size()model; - int id = source->getMTGId(); - list::iterator it; - for ( it=stats.begin() ; it != stats.end(); it++ ){ - if (n >= max) return false; - AIStat * stat = *it; - if (stat->source == id){ - if (stat->value>=0) return true; - return false; - } - n++; - } - return false; -} - -AIStat * AIStats::find(MTGCard * source){ - int id = source->getMTGId(); - list::iterator it; - for ( it=stats.begin() ; it != stats.end(); it++ ){ - AIStat * stat = *it; - if (stat->source == id) return stat; - } - return NULL; -} - -void AIStats::load(char * filename){ - std::ifstream file(filename); +#include "../include/debug.h" +#include "../include/AIStats.h" +#include "../include/GameObserver.h" +#include "../include/Player.h" +#include "../include/MTGCardInstance.h" + +bool compare_aistats(AIStat * first, AIStat * second){ + float damage1 = first->value / first->occurences; + float damage2 = second->value/ second->occurences; + return (damage1 > damage2); +} + +AIStats::AIStats(Player * _player, char * _filename){ + filename = _filename; + load(_filename); + player = _player; +} + +AIStats::~AIStats(){ + list::iterator it; + for ( it=stats.begin() ; it != stats.end(); it++ ){ + AIStat * stat = *it; + delete stat; + } +} + +void AIStats::updateStatsCard(MTGCardInstance * cardInstance, Damage * damage, float multiplier){ + MTGCard * card = cardInstance->model; + AIStat * stat = find(card); + if (!stat){ + stat = NEW AIStat(card->getMTGId(),0,1,0); + stats.push_back(stat); + } + if (damage->target == player){ + stat->value+= multiplier * STATS_PLAYER_MULTIPLIER * damage->damage; + }else if (damage->target->type_as_damageable == DAMAGEABLE_MTGCARDINSTANCE){ + MTGCardInstance * target = (MTGCardInstance *)damage->target; + if (target->controller() == player && !target->isInPlay()){ + //One of my creatures got lethal damage... + stat->value+= multiplier * STATS_CREATURE_MULTIPLIER * damage->damage; + } + } +} + +void AIStats::updateStats(){ + GameObserver * game = GameObserver::GetInstance(); + ActionStack * as = game->mLayers->stackLayer(); + Damage * damage = ((Damage * )as->getNext(NULL,ACTION_DAMAGE, RESOLVED_OK)); + MTGGameZone * opponentZone = player->opponent()->game->inPlay; + while(damage){ + MTGCardInstance * card = damage->source; + updateStatsCard(card,damage); + + //Auras on damage source can be the cause + for (int i=0; i < opponentZone->nb_cards; i++){ + MTGCardInstance * aura = opponentZone->cards[i]; + if (aura->target == card){ + updateStatsCard(aura,damage, STATS_AURA_MULTIPLIER); + } + } + damage = ((Damage * )as->getNext(damage,ACTION_DAMAGE, RESOLVED_OK)); + } + stats.sort(compare_aistats); + save(); +} + +bool AIStats::isInTop(MTGCardInstance * card, unsigned int max, bool tooSmallCountsForTrue ){ + if (stats.size()model; + int id = source->getMTGId(); + list::iterator it; + for ( it=stats.begin() ; it != stats.end(); it++ ){ + if (n >= max) return false; + AIStat * stat = *it; + if (stat->source == id){ + if (stat->value>=0) return true; + return false; + } + n++; + } + return false; +} + +AIStat * AIStats::find(MTGCard * source){ + int id = source->getMTGId(); + list::iterator it; + for ( it=stats.begin() ; it != stats.end(); it++ ){ + AIStat * stat = *it; + if (stat->source == id) return stat; + } + return NULL; +} + +void AIStats::load(char * filename){ + std::ifstream file(filename); std::string s; - if(file){ - while(std::getline(file,s)){ - int cardid = atoi(s.c_str()); - std::getline(file,s); - int value = atoi(s.c_str()); - std::getline(file,s); - int direct = atoi(s.c_str()); - AIStat * stat = NEW AIStat(cardid,value,1,direct); - stats.push_back(stat); - } - file.close(); - }else{ - //TODO Error management - } -} -void AIStats::save(){ - std::ofstream file(filename.c_str()); - char writer[128]; - if (file){ - list::iterator it; - for ( it=stats.begin() ; it != stats.end(); it++ ){ - AIStat * stat = *it; - if (stat->value > 0){ - sprintf(writer,"%i\n%i\n%i\n", stat->source,stat->value/2,stat->direct); - file<::iterator it; + for ( it=stats.begin() ; it != stats.end(); it++ ){ + AIStat * stat = *it; + if (stat->value > 0){ + sprintf(writer,"%i\n%i\n%i\n", stat->source,stat->value/2,stat->direct); + file<FillRect(0,y0,SCREEN_WIDTH,height/2,colors_up); renderer->FillRect(0,y0+height/2,SCREEN_WIDTH,height/2,colors_down); // mEngine->DrawLine(0,y0,SCREEN_WIDTH,y0,ARGB(128,255,255,255)); // mEngine->DrawLine(0,y0+height,SCREEN_WIDTH,y0+height,ARGB(128,255,255,255)); -}*/ + }*/ int ActionElement::getActivity(){ - return activeState; + return activeState; } int ActionElement::isReactingToTargetClick(Targetable * object){ - if (object && object->typeAsTarget() == TARGET_CARD) return isReactingToClick((MTGCardInstance *)object); - return 0; + if (object && object->typeAsTarget() == TARGET_CARD) return isReactingToClick((MTGCardInstance *)object); + return 0; } int ActionElement::reactToTargetClick(Targetable * object){ - if (object->typeAsTarget() == TARGET_CARD) return reactToClick((MTGCardInstance *)object); - return 0; -} \ No newline at end of file + if (object->typeAsTarget() == TARGET_CARD) return reactToClick((MTGCardInstance *)object); + return 0; +} diff --git a/projects/mtg/src/ActionLayer.cpp b/projects/mtg/src/ActionLayer.cpp index 91571bbe4..e48d29ca5 100644 --- a/projects/mtg/src/ActionLayer.cpp +++ b/projects/mtg/src/ActionLayer.cpp @@ -5,195 +5,195 @@ int ActionLayer::unstopableRenderInProgress(){ - for (int i=0;igetActivity() > 0){ - return 1; - } - } - } - return 0; + for (int i=0;igetActivity() > 0){ + return 1; + } + } + } + return 0; } void ActionLayer::CheckUserInput(float dt){ - if (menuObject){ - abilitiesMenu->Update(dt); - return; - } - for (int i=0;iCheckUserInput(dt); - } - } + if (menuObject){ + abilitiesMenu->Update(dt); + return; + } + for (int i=0;iCheckUserInput(dt); + } + } } void ActionLayer::Update(float dt){ - if (menuObject){ - return; - } - modal = 0; - for (int i=mCount -1 ;i>=0;i--){ - if (mObjects[i]!= NULL){ - ActionElement * currentAction = (ActionElement *)mObjects[i]; - if (currentAction->testDestroy()){ - currentAction->destroy(); - Remove(currentAction); - } - } - } - int newPhase = GameObserver::GetInstance()->getCurrentGamePhase(); - for (int i=0;inewPhase = newPhase; - currentAction->Update(dt); - currentAction->currentPhase = newPhase; - } - } + if (menuObject){ + return; + } + modal = 0; + for (int i=mCount -1 ;i>=0;i--){ + if (mObjects[i]!= NULL){ + ActionElement * currentAction = (ActionElement *)mObjects[i]; + if (currentAction->testDestroy()){ + currentAction->destroy(); + Remove(currentAction); + } + } + } + int newPhase = GameObserver::GetInstance()->getCurrentGamePhase(); + for (int i=0;inewPhase = newPhase; + currentAction->Update(dt); + currentAction->currentPhase = newPhase; + } + } } void ActionLayer::Render (){ - if (menuObject){ - abilitiesMenu->Render(); - return; - } - for (int i=0;igetActivity() > 0){ - currentAction->Render(); - //return; - //} - } - } + if (menuObject){ + abilitiesMenu->Render(); + return; + } + for (int i=0;igetActivity() > 0){ + currentAction->Render(); + //return; + //} + } + } } TargetChooser * ActionLayer::getCurrentTargetChooser(){ - for (int i=0;iwaitingForAnswer) return currentAction->tc; - } - return NULL; + for (int i=0;iwaitingForAnswer) return currentAction->tc; + } + return NULL; } int ActionLayer::isWaitingForAnswer(){ - for (int i=0;iwaitingForAnswer) return 1; - } - return 0; + for (int i=0;iwaitingForAnswer) return 1; + } + return 0; } int ActionLayer::isReactingToTargetClick(Targetable * card){ - int result = 0; + int result = 0; - if (isWaitingForAnswer()) return -1; + if (isWaitingForAnswer()) return -1; - for (int i=0;iisReactingToTargetClick(card); - } - return result; + for (int i=0;iisReactingToTargetClick(card); + } + return result; } int ActionLayer::reactToTargetClick(Targetable * card){ - int result = 0; + int result = 0; - for (int i=0;iwaitingForAnswer){ - return currentAction->reactToTargetClick(card); - } - } + for (int i=0;iwaitingForAnswer){ + return currentAction->reactToTargetClick(card); + } + } - for (int i=0;ireactToTargetClick(card); - } - return result; + for (int i=0;ireactToTargetClick(card); + } + return result; } //TODO Simplify with only object !!! int ActionLayer::isReactingToClick(MTGCardInstance * card){ - int result = 0; + int result = 0; - for (int i=0;iwaitingForAnswer) return -1; - } + for (int i=0;iwaitingForAnswer) return -1; + } - for (int i=0;iisReactingToClick(card); - } + for (int i=0;iisReactingToClick(card); + } - return result; + return result; } int ActionLayer::reactToClick(MTGCardInstance * card){ - int result = 0; + int result = 0; - for (int i=0;iwaitingForAnswer){ - return currentAction->reactToClick(card); - } - } + for (int i=0;iwaitingForAnswer){ + return currentAction->reactToClick(card); + } + } - for (int i=0;ireactToClick(card); - } - return result; + for (int i=0;ireactToClick(card); + } + return result; } int ActionLayer::isModal(){ - if (modal) return 1; - if (menuObject) return 1; - for (int i=0; imodal) return 1; - } - return 0; + if (modal) return 1; + if (menuObject) return 1; + for (int i=0; imodal) return 1; + } + return 0; } void ActionLayer::setMenuObject(Targetable * object){ - menuObject = object; - if (abilitiesMenu){ - delete abilitiesMenu; - } - JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); - abilitiesMenu = NEW SimpleMenu(10, this, mFont, 100, 100, 200); - - for (int i=0;iisReactingToTargetClick(object)){ - abilitiesMenu->Add(i,currentAction->getMenuText()); - } - } - abilitiesMenu->Add(-1, "Cancel"); - modal = 1; + menuObject = object; + if (abilitiesMenu){ + delete abilitiesMenu; + } + JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); + abilitiesMenu = NEW SimpleMenu(10, this, mFont, 100, 100, 200); + + for (int i=0;iisReactingToTargetClick(object)){ + abilitiesMenu->Add(i,currentAction->getMenuText()); + } + } + abilitiesMenu->Add(-1, "Cancel"); + modal = 1; } void ActionLayer::ButtonPressed(int controllerid, int controlid){ - if (controlid == -1){ + if (controlid == -1){ - }else{ - ActionElement * currentAction = (ActionElement *)mObjects[controlid]; - currentAction->reactToTargetClick(menuObject); - } - menuObject = 0; + }else{ + ActionElement * currentAction = (ActionElement *)mObjects[controlid]; + currentAction->reactToTargetClick(menuObject); + } + menuObject = 0; -} \ No newline at end of file +} diff --git a/projects/mtg/src/ActionStack.cpp b/projects/mtg/src/ActionStack.cpp index 8653f8fe3..8f404494f 100644 --- a/projects/mtg/src/ActionStack.cpp +++ b/projects/mtg/src/ActionStack.cpp @@ -1,690 +1,690 @@ -/* -The Action Stack contains all information for Game Events that can be interrupted (Interruptible) -*/ -#include "../include/debug.h" -#include "../include/ActionStack.h" -#include "../include/MTGAbility.h" -#include "../include/GameObserver.h" -#include "../include/Damage.h" -#include "../include/ManaCost.h" - -/* -NextGamePhase requested by user -*/ - -int NextGamePhase::resolve(){ - GameObserver::GetInstance()->nextGamePhase(); - return 1; -} - -void NextGamePhase::Render(){ - int nextPhase = (GameObserver::GetInstance()->getCurrentGamePhase() + 1) % MTG_PHASE_CLEANUP; - JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); - mFont->SetBase(0); - mFont->SetScale(0.75); - char buffer[200]; - int playerId = 1; - if (GameObserver::GetInstance()->currentActionPlayer == GameObserver::GetInstance()->players[1]) playerId = 2; - sprintf(buffer, "Player %i : -> %s", playerId, MTGPhaseNames[nextPhase]); - mFont->DrawString(buffer, x + 20 , y, JGETEXT_LEFT); -} - -NextGamePhase::NextGamePhase(int id): Interruptible(id){ - mHeight = 40; - type = ACTION_NEXTGAMEPHASE; -} - - -/* Ability */ -int StackAbility::resolve(){ - return (ability->resolve()); -} -void StackAbility::Render(){ - JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); - mFont->SetBase(0); - mFont->SetScale(0.75); - char buffer[200]; - sprintf(buffer, "%s", ability->getMenuText()); - mFont->DrawString(buffer, x + 20 , y, JGETEXT_LEFT); - JRenderer * renderer = JRenderer::GetInstance(); - JQuad * quad = ability->source->getThumb(); - if (quad){ - float scale = 30 / quad->mHeight; - renderer->RenderQuad(quad, x , y , 0,scale,scale); - }else{ - //TODO - } -} -StackAbility::StackAbility(int id,MTGAbility * _ability): Interruptible(id),ability(_ability){ - type=ACTION_ABILITY; -} - - -/* Spell Cast */ - -Spell::Spell(MTGCardInstance * _source): Interruptible(0), TargetsList(){ - source = _source; - mHeight= 40; - type = ACTION_SPELL; - cost = NEW ManaCost(); -} - - -Spell::Spell(int id, MTGCardInstance * _source, Targetable * _targets[], int nb_targets, ManaCost * _cost): Interruptible(id), TargetsList(_targets, nb_targets),cost(_cost){ - source = _source; - mHeight = 40; - type = ACTION_SPELL; -} - - -Spell::~Spell(){ - SAFE_DELETE(cost); -} - -int Spell::resolve(){ - GameObserver * game = GameObserver::GetInstance(); - //TODO Remove target if it's not targettable anymore - source->controller()->game->putInPlay(source); - AbilityFactory af; - af.addAbilities(game->mLayers->actionLayer()->getMaxId(), this); - return 1; -} - -void Spell::Render(){ - JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); - mFont->SetBase(0); - mFont->SetScale(0.75); - char buffer[200]; - sprintf(buffer, "%s", source->model->getName()); - mFont->DrawString(buffer, x + 20 , y, JGETEXT_LEFT); - JRenderer * renderer = JRenderer::GetInstance(); - JQuad * quad = source->getThumb(); - if (quad){ - float scale = mHeight / quad->mHeight; - renderer->RenderQuad(quad, x , y , 0,scale,scale); - }else{ - //TODO - } - Damageable * target = getNextDamageableTarget(); - if (target){ - quad = target->getIcon(); - if (quad){ - float scale = 30 / quad->mHeight; - renderer->RenderQuad(quad, x + 150 , y , 0,scale,scale); - } - } -} - - -/* Put a card in graveyard */ - -PutInGraveyard::PutInGraveyard(int id, MTGCardInstance * _card):Interruptible(id){ - card = _card; - removeFromGame = 0; - type = ACTION_PUTINGRAVEYARD; -} - -int PutInGraveyard::resolve(){ - GameObserver * g = GameObserver::GetInstance(); - MTGGameZone * zone = card->getCurrentZone(); - if (zone == g->players[0]->game->inPlay || zone == g->players[1]->game->inPlay){ - card->owner->game->putInZone(card,zone,card->owner->game->graveyard); - return 1; - } - return 0; -} - -void PutInGraveyard::Render(){ - JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); - mFont->SetBase(0); - mFont->SetScale(0.75); - if (!removeFromGame){ - mFont->DrawString("goes to graveyard", x + 20 , y, JGETEXT_LEFT); - }else{ - mFont->DrawString("is removed from game", x + 20 , y, JGETEXT_LEFT); - } - JRenderer * renderer = JRenderer::GetInstance(); - JQuad * quad = card->getThumb(); - if (quad){ - float scale = 30 / quad->mHeight; - renderer->RenderQuad(quad, x , y , 0,scale,scale); - }else{ - //TODO - } -} - - -/* Draw a Card */ -DrawAction::DrawAction(int id, Player * _player, int _nbcards):Interruptible(id), nbcards(_nbcards), player(_player){ -} - -int DrawAction::resolve(){ - for (int i = 0 ; i < nbcards ; i++){ - player->game->drawFromLibrary(); - } - return 1; -} - -void DrawAction::Render(){ - JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); - mFont->SetBase(0); - mFont->SetScale(0.75); - char buffer[200]; - int playerId = 1; - if (player == GameObserver::GetInstance()->players[1]) playerId = 2; - sprintf(buffer, "Player %i draws %i card", playerId, nbcards); - mFont->DrawString(buffer, x + 20 , y, JGETEXT_LEFT); -} - -/* The Action Stack itself */ -int ActionStack::addPutInGraveyard(MTGCardInstance * card){ - PutInGraveyard * death = NEW PutInGraveyard(mCount,card); - addAction(death); - return 1; -} - -int ActionStack::addAbility(MTGAbility * ability){ - StackAbility * stackAbility = NEW StackAbility(mCount,ability); - addAction(stackAbility); - return 1; -} - -int ActionStack::addDraw(Player * player, int nb_cards){ - DrawAction * draw = NEW DrawAction(mCount,player, nb_cards); - addAction(draw); - return 1; -} - -int ActionStack::addDamage(MTGCardInstance * _source, Damageable * _target, int _damage){ - Damage * damage = NEW Damage(mCount, _source, _target, _damage); - addAction(damage); - return 1; -} - -int ActionStack::AddNextGamePhase(){ - if (getNext(NULL,NOT_RESOLVED)) return 0; - NextGamePhase * next = NEW NextGamePhase(mCount); - addAction(next); - int playerId = 0; - if (game->currentActionPlayer == game->players[1]) playerId = 1; - interruptDecision[playerId] = 1; - return 1; -} - -int ActionStack::setIsInterrupting(Player * player){ - if (player == game->players[0]){ - interruptDecision[0] = -1; - }else{ - interruptDecision[1] = -1; - } - game->isInterrupting = player; - askIfWishesToInterrupt = NULL; - return 1; -} - - -int ActionStack::addAction(Interruptible * action){ - for (int i=0; i<2; i++){ - interruptDecision[i] = 0; - } - Add(action); - return 1; -} - -int ActionStack::addSpell(MTGCardInstance * _source, Targetable * _targets[], int _nbtargets, ManaCost * mana){ -#if defined (WIN32) || defined (LINUX) -char buf[4096], *p = buf; -sprintf(buf, "Add spell\n"); -OutputDebugString(buf); -#endif - Spell * spell = NEW Spell(mCount,_source,_targets,_nbtargets, mana); - return addAction(spell); -} - - -Interruptible * ActionStack::_(int id){ - if (id < 0) id = mCount + id; - if (id > mCount -1) return NULL; - return (Interruptible *)mObjects[id]; -} - -ActionStack::ActionStack(int id, GameObserver* _game):GuiLayer(id, _game){ - for (int i=0; i<2; i++){ - interruptDecision[i] = 0; - } - askIfWishesToInterrupt = NULL; - timer = -1; - currentState = -1; - mode = ACTIONSTACK_STANDARD; - checked = 0; - -} - -int ActionStack::has(Interruptible * action){ - for (int i = 0; i < mCount ; i++){ - if (mObjects[i] == action) return 1; - } - return 0; -} - -int ActionStack::resolve(){ - Interruptible * action = getLatest(NOT_RESOLVED); - - if (!action) - return 0; - - - if (action->resolve()){ - action->state = RESOLVED_OK; - }else{ - action->state = RESOLVED_NOK; - } - if (action->type == ACTION_DAMAGE) ((Damage * )action)->target->afterDamage(); - if (action->type == ACTION_DAMAGES){ - DamageStack * ds = (DamageStack *) action; - for (int i = 0; i < ds->mCount; i++){ - Damage * damage = ((Damage *) ds->mObjects[i]); - damage->state = ds->state; - } - unpackDamageStack(ds); - ds->mCount = 0; - } - - if (!getNext(NULL,NOT_RESOLVED)){ - for (int i = 0; i< 2 ; i++){ - interruptDecision[i] = 0; - } - }else{ - for (int i = 0; i< 2 ; i++){ - if (interruptDecision[i] != 2) interruptDecision[i] = 0; - } - } - - return 1; - -} - -Interruptible * ActionStack::getPrevious(Interruptible * next, int type, int state, int display){ - int n = getPreviousIndex( next, type, state, display); - if (n==-1) return NULL; - return ((Interruptible *) mObjects[n]); -} - -int ActionStack::getPreviousIndex(Interruptible * next, int type, int state, int display){ - int found = 0; - if (!next) found = 1; - for (int i = mCount -1; i >= 0 ; i--){ - Interruptible * current = (Interruptible *)mObjects[i]; - if (found && (type == 0 || current->type == type) && (state == 0 || current->state == state) && (display == -1 || current->display == display)){ - return i; - } - if (current == next) found = 1; - } - if (!found) return getPreviousIndex(NULL,type, state, display); - return -1; -} - -int ActionStack::count( int type, int state, int display){ - int result = 0; - for (int i = 0; i < mCount ; i++){ - Interruptible * current = (Interruptible *)mObjects[i]; - if((type == 0 || current->type == type) && (state == 0 || current->state == state) && (display == -1 || current->display == display)){ - result++; - } - } - return result; -} - -Interruptible * ActionStack::getNext(Interruptible * previous, int type, int state, int display){ - int n = getNextIndex( previous, type, state, display); - if (n==-1) return NULL; - return ((Interruptible *) mObjects[n]); -} - -int ActionStack::getNextIndex(Interruptible * previous, int type, int state, int display){ - int found = 0; - if (!previous) found = 1; - for (int i = 0; i < mCount ; i++){ - Interruptible * current = (Interruptible *)mObjects[i]; - if (found && (type == 0 || current->type == type) && (state == 0 || current->state == state) && (display == -1 || current->display == display)){ - return i; - } - if (current == previous) found = 1; - } - if (!found) return getNextIndex(NULL,type, state, display); - return -1; -} - - -Interruptible * ActionStack::getLatest(int state){ - for (int i = mCount-1; i >=0; i--){ - Interruptible * action = ((Interruptible *)mObjects[i]); - if (action->state == state) return action; - } - return NULL; -} - -void ActionStack::unpackDamageStack(DamageStack * ds){ - for (int j = 0; j < ds->mCount; j++){ - Damage * damage = ((Damage *)ds->mObjects[j]); - Add(damage); - } -} - -void ActionStack::unpackDamageStacks(){ - for (int i = mCount-1; i >=0; i--){ - Interruptible * action = ((Interruptible *)mObjects[i]); - if (action->type == ACTION_DAMAGES){ - DamageStack * ds = (DamageStack *) action; - unpackDamageStack(ds); - } - } -} - -void ActionStack::repackDamageStacks(){ - for (int i = mCount-1; i >=0; i--){ - Interruptible * action = ((Interruptible *)mObjects[i]); - if (action->type == ACTION_DAMAGE){ - Damage * damage = (Damage *) action; - for (int j = 0; j < mCount; j++){ - Interruptible * action2 = ((Interruptible *)mObjects[j]); - if (action->type == ACTION_DAMAGES){ - DamageStack * ds = (DamageStack *) action2; - for (int k = 0; k< ds->mCount; k++){ - Damage * dsdamage = ((Damage *)ds->mObjects[k]); - if (dsdamage==damage) Remove(damage); - } - } - } - } - } -} - -void ActionStack::Update(float dt){ - askIfWishesToInterrupt = NULL; - //modal = 0; - GameObserver * game = GameObserver::GetInstance(); - TargetChooser * tc = game->getCurrentTargetChooser(); - int newState = game->getCurrentGamePhase(); - currentState = newState; - - //Select Stack's display mode - if (mode==ACTIONSTACK_STANDARD && tc && !checked){ - checked = 1; - unpackDamageStacks(); - for (int i = 0; i < mCount ; i++){ - Interruptible * current = (Interruptible *)mObjects[i]; - if (tc->canTarget(current)){ - if (mObjects[mCurr]) mObjects[mCurr]->Leaving(PSP_CTRL_UP); - current->display = 1; - mCurr = i; - mObjects[mCurr]->Entering(); - mode=ACTIONSTACK_TARGET; - modal = 1; - }else{ - current->display = 0; - } - } - if (mode != ACTIONSTACK_TARGET){ - repackDamageStacks(); - } - }else if (mode==ACTIONSTACK_TARGET && !tc){ - mode = ACTIONSTACK_STANDARD; - checked = 0; - repackDamageStacks(); - } - - if (mode == ACTIONSTACK_STANDARD){ - modal = 0; - if (getLatest(NOT_RESOLVED)){ - int currentPlayerId = 0; - int otherPlayerId = 1; - if (game->currentPlayer != game->players[0]){ - currentPlayerId = 1; - otherPlayerId = 0; - } - if (interruptDecision[currentPlayerId] == 0){ - askIfWishesToInterrupt = game->players[currentPlayerId]; - game->isInterrupting = game->players[currentPlayerId]; - modal = 1; - }else if (interruptDecision[currentPlayerId] == -1){ - game->isInterrupting = game->players[currentPlayerId]; - - }else{ - if (interruptDecision[otherPlayerId] == 0){ - askIfWishesToInterrupt = game->players[otherPlayerId]; - game->isInterrupting = game->players[otherPlayerId]; - modal = 1; - }else if (interruptDecision[otherPlayerId] == -1){ - game->isInterrupting = game->players[otherPlayerId]; - }else{ - resolve(); - } - } - } - }else if (mode == ACTIONSTACK_TARGET){ - GuiLayer::Update(dt); - } -} - -void ActionStack::cancelInterruptOffer(int cancelMode){ - if (askIfWishesToInterrupt == game->players[0]){ - interruptDecision[0] = cancelMode; - }else{ - interruptDecision[1] = cancelMode; - } - askIfWishesToInterrupt = NULL; - game->isInterrupting = NULL; - timer = -1; -} - -void ActionStack::endOfInterruption(){ - if (game->isInterrupting == game->players[0]){ - interruptDecision[0] = 0; - }else{ - interruptDecision[1] = 0; - } - game->isInterrupting = NULL; -} - - -void ActionStack::CheckUserInput(float dt){ - if (mode == ACTIONSTACK_STANDARD){ - if (askIfWishesToInterrupt){ - if (timer < 0) timer = 300; - if (mEngine->GetButtonClick(PSP_CTRL_CROSS)){ - setIsInterrupting(askIfWishesToInterrupt); - }else if (mEngine->GetButtonClick(PSP_CTRL_CIRCLE) ||mEngine->GetButtonClick(PSP_CTRL_RTRIGGER) ){ - cancelInterruptOffer(); - }else if (mEngine->GetButtonClick(PSP_CTRL_SQUARE)){ - cancelInterruptOffer(2); - }else{ - timer --; - if (timer < 0){ - cancelInterruptOffer(); - } - } - }else if (game->isInterrupting){ - if (mEngine->GetButtonClick(PSP_CTRL_CROSS)){ - endOfInterruption(); - } - } - }else if (mode == ACTIONSTACK_TARGET){ - if (modal){ - if (mEngine->GetButtonState(PSP_CTRL_UP)){ - if (KeyRepeated(PSP_CTRL_UP, dt)) - { - if( mObjects[mCurr]){ - int n = getPreviousIndex(((Interruptible *) mObjects[mCurr]), 0, 0, 1); - if (n != -1 && n != mCurr && mObjects[mCurr]->Leaving(PSP_CTRL_UP)) - { - mCurr = n; - mObjects[mCurr]->Entering(); -#if defined (WIN32) || defined (LINUX) - char buf[4096]; - sprintf(buf, "Stack UP TO mCurr = %i\n", mCurr); - OutputDebugString(buf); -#endif - } - } - } - }else if (mEngine->GetButtonState(PSP_CTRL_DOWN)){ - if (KeyRepeated(PSP_CTRL_DOWN, dt)) - { - if( mObjects[mCurr]){ - int n = getNextIndex(((Interruptible *) mObjects[mCurr]), 0, 0, 1); - if (n!= -1 && n != mCurr && mObjects[mCurr]->Leaving(PSP_CTRL_DOWN)) - { - mCurr = n; - mObjects[mCurr]->Entering(); -#if defined (WIN32) || defined (LINUX) - char buf[4096]; - sprintf(buf, "Stack DOWN TO mCurr = %i\n", mCurr); - OutputDebugString(buf); -#endif - } - } - } - }else if (mEngine->GetButtonClick(PSP_CTRL_CIRCLE)){ -#if defined (WIN32) || defined (LINUX) - char buf[4096]; - sprintf(buf, "Stack CLIKED mCurr = %i\n", mCurr); - OutputDebugString(buf); -#endif - game->stackObjectClicked(((Interruptible *) mObjects[mCurr])); - } - } - if (mEngine->GetButtonClick(PSP_CTRL_TRIANGLE)){ - if (modal) {modal = 0;} else {modal = 1;} - } - } -} - - - - -int ActionStack::CombatDamages(){ - CombatDamages(1); - CombatDamages(0); - return 1; -} - -int ActionStack::CombatDamages(int strike){ - DamageStack * damages = NEW DamageStack(mCount,game); - int damageitems = damages->CombatDamages(strike); - if (damageitems){ - addAction(damages); - }else{ - delete damages; - } - return damageitems; -} - -//Cleans history of last turn -int ActionStack::garbageCollect(){ - for (int i=mCount-1;i>=0; i--){ - Interruptible * current = ((Interruptible *)mObjects[i]); - if (current->state != NOT_RESOLVED){ - mObjects[i] = mObjects[mCount-1]; - mCount--; - delete current; - } - } - return 1; -} - -void ActionStack::Fizzle(Interruptible * action){ - if (action->type == ACTION_SPELL){ - Spell * spell = (Spell *) action; - spell->source->controller()->game->putInGraveyard(spell->source); - } - action->state = RESOLVED_NOK; -} - -void ActionStack::Render(){ - int x0 = 250; - int y0 = 30; - int width = 200; - int height = 90; - int currenty = y0 + 5 ; - - if (mode == ACTIONSTACK_STANDARD){ - if (!askIfWishesToInterrupt || !askIfWishesToInterrupt->displayStack()) return; - - - for (int i=0;istate==NOT_RESOLVED) height += current->mHeight; - } - - JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); - mFont->SetBase(0); - mFont->SetScale(0.75); - - JRenderer * renderer = JRenderer::GetInstance(); - - //JQuad * back = GameApp::CommonRes->GetQuad("interrupt"); - //float xScale = width / back->mWidth; - //float yScale = height / back->mHeight; - renderer->FillRoundRect(x0 + 16 ,y0 + 16 ,width +2 ,height +2 , 10, ARGB(128,0,0,0)); - renderer->FillRoundRect(x0 - 5 ,y0 - 5 ,width + 2,height +2 , 10, ARGB(200,0,0,0)); - //renderer->RenderQuad(back,x0,y0,0,xScale, yScale); - renderer->DrawRoundRect(x0 - 5 ,y0 - 5 ,width + 2,height +2 , 10, ARGB(255,255,255,255)); - - - for (int i=0;istate==NOT_RESOLVED){ - current->x = x0 + 5; - if (i != mCount -1){ - current->y = currenty; - currenty += current->mHeight; - }else{ - current->y = currenty + 40 ; - currenty += current->mHeight + 40; - } - current->Render(); - } - } - - char buffer[200]; - sprintf(buffer, "interrupt ? %i", timer/100); - mFont->DrawString(buffer, x0 + 5 , currenty - 40 - ((Interruptible *)mObjects[mCount-1])->mHeight); - - if (mCount > 1){ - sprintf(buffer, "X Interrupt - 0 No - [] No to All"); - }else{ - sprintf(buffer, "X Interrupt - 0 No"); - } - mFont->DrawString(buffer, x0 + 5 , currenty); - }else if (mode == ACTIONSTACK_TARGET && modal){ - for (int i=0;idisplay) height += current->mHeight; - } - - JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); - mFont->SetBase(0); - mFont->SetScale(0.75); - - JRenderer * renderer = JRenderer::GetInstance(); - renderer->FillRect(x0 ,y0 , width ,height , ARGB(200,0,0,0)); - renderer->DrawRect(x0 - 1 ,y0 - 1 ,width + 2 ,height +2 , ARGB(255,255,255,255)); - - - for (int i=0;idisplay){ - ((Interruptible *)mObjects[i])->x = x0 + 5; - if (i != mCount -1){ - ((Interruptible *)mObjects[i])->y = currenty; - currenty += ((Interruptible *)mObjects[i])->mHeight; - }else{ - ((Interruptible *)mObjects[i])->y = currenty + 40 ; - currenty += ((Interruptible *)mObjects[i])->mHeight + 40; - } - mObjects[i]->Render(); - } - } - } -} +/* + The Action Stack contains all information for Game Events that can be interrupted (Interruptible) +*/ +#include "../include/debug.h" +#include "../include/ActionStack.h" +#include "../include/MTGAbility.h" +#include "../include/GameObserver.h" +#include "../include/Damage.h" +#include "../include/ManaCost.h" + +/* + NextGamePhase requested by user +*/ + +int NextGamePhase::resolve(){ + GameObserver::GetInstance()->nextGamePhase(); + return 1; +} + +void NextGamePhase::Render(){ + int nextPhase = (GameObserver::GetInstance()->getCurrentGamePhase() + 1) % MTG_PHASE_CLEANUP; + JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); + mFont->SetBase(0); + mFont->SetScale(0.75); + char buffer[200]; + int playerId = 1; + if (GameObserver::GetInstance()->currentActionPlayer == GameObserver::GetInstance()->players[1]) playerId = 2; + sprintf(buffer, "Player %i : -> %s", playerId, MTGPhaseNames[nextPhase]); + mFont->DrawString(buffer, x + 20 , y, JGETEXT_LEFT); +} + +NextGamePhase::NextGamePhase(int id): Interruptible(id){ + mHeight = 40; + type = ACTION_NEXTGAMEPHASE; +} + + +/* Ability */ +int StackAbility::resolve(){ + return (ability->resolve()); +} +void StackAbility::Render(){ + JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); + mFont->SetBase(0); + mFont->SetScale(0.75); + char buffer[200]; + sprintf(buffer, "%s", ability->getMenuText()); + mFont->DrawString(buffer, x + 20 , y, JGETEXT_LEFT); + JRenderer * renderer = JRenderer::GetInstance(); + JQuad * quad = ability->source->getThumb(); + if (quad){ + float scale = 30 / quad->mHeight; + renderer->RenderQuad(quad, x , y , 0,scale,scale); + }else{ + //TODO + } +} +StackAbility::StackAbility(int id,MTGAbility * _ability): Interruptible(id),ability(_ability){ + type=ACTION_ABILITY; +} + + +/* Spell Cast */ + +Spell::Spell(MTGCardInstance * _source): Interruptible(0), TargetsList(){ + source = _source; + mHeight= 40; + type = ACTION_SPELL; + cost = NEW ManaCost(); +} + + +Spell::Spell(int id, MTGCardInstance * _source, Targetable * _targets[], int nb_targets, ManaCost * _cost): Interruptible(id), TargetsList(_targets, nb_targets),cost(_cost){ + source = _source; + mHeight = 40; + type = ACTION_SPELL; +} + + +Spell::~Spell(){ + SAFE_DELETE(cost); +} + +int Spell::resolve(){ + GameObserver * game = GameObserver::GetInstance(); + //TODO Remove target if it's not targettable anymore + source->controller()->game->putInPlay(source); + AbilityFactory af; + af.addAbilities(game->mLayers->actionLayer()->getMaxId(), this); + return 1; +} + +void Spell::Render(){ + JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); + mFont->SetBase(0); + mFont->SetScale(0.75); + char buffer[200]; + sprintf(buffer, "%s", source->model->getName()); + mFont->DrawString(buffer, x + 20 , y, JGETEXT_LEFT); + JRenderer * renderer = JRenderer::GetInstance(); + JQuad * quad = source->getThumb(); + if (quad){ + float scale = mHeight / quad->mHeight; + renderer->RenderQuad(quad, x , y , 0,scale,scale); + }else{ + //TODO + } + Damageable * target = getNextDamageableTarget(); + if (target){ + quad = target->getIcon(); + if (quad){ + float scale = 30 / quad->mHeight; + renderer->RenderQuad(quad, x + 150 , y , 0,scale,scale); + } + } +} + + +/* Put a card in graveyard */ + +PutInGraveyard::PutInGraveyard(int id, MTGCardInstance * _card):Interruptible(id){ + card = _card; + removeFromGame = 0; + type = ACTION_PUTINGRAVEYARD; +} + +int PutInGraveyard::resolve(){ + GameObserver * g = GameObserver::GetInstance(); + MTGGameZone * zone = card->getCurrentZone(); + if (zone == g->players[0]->game->inPlay || zone == g->players[1]->game->inPlay){ + card->owner->game->putInZone(card,zone,card->owner->game->graveyard); + return 1; + } + return 0; +} + +void PutInGraveyard::Render(){ + JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); + mFont->SetBase(0); + mFont->SetScale(0.75); + if (!removeFromGame){ + mFont->DrawString("goes to graveyard", x + 20 , y, JGETEXT_LEFT); + }else{ + mFont->DrawString("is removed from game", x + 20 , y, JGETEXT_LEFT); + } + JRenderer * renderer = JRenderer::GetInstance(); + JQuad * quad = card->getThumb(); + if (quad){ + float scale = 30 / quad->mHeight; + renderer->RenderQuad(quad, x , y , 0,scale,scale); + }else{ + //TODO + } +} + + +/* Draw a Card */ +DrawAction::DrawAction(int id, Player * _player, int _nbcards):Interruptible(id), nbcards(_nbcards), player(_player){ +} + +int DrawAction::resolve(){ + for (int i = 0 ; i < nbcards ; i++){ + player->game->drawFromLibrary(); + } + return 1; +} + +void DrawAction::Render(){ + JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); + mFont->SetBase(0); + mFont->SetScale(0.75); + char buffer[200]; + int playerId = 1; + if (player == GameObserver::GetInstance()->players[1]) playerId = 2; + sprintf(buffer, "Player %i draws %i card", playerId, nbcards); + mFont->DrawString(buffer, x + 20 , y, JGETEXT_LEFT); +} + +/* The Action Stack itself */ +int ActionStack::addPutInGraveyard(MTGCardInstance * card){ + PutInGraveyard * death = NEW PutInGraveyard(mCount,card); + addAction(death); + return 1; +} + +int ActionStack::addAbility(MTGAbility * ability){ + StackAbility * stackAbility = NEW StackAbility(mCount,ability); + addAction(stackAbility); + return 1; +} + +int ActionStack::addDraw(Player * player, int nb_cards){ + DrawAction * draw = NEW DrawAction(mCount,player, nb_cards); + addAction(draw); + return 1; +} + +int ActionStack::addDamage(MTGCardInstance * _source, Damageable * _target, int _damage){ + Damage * damage = NEW Damage(mCount, _source, _target, _damage); + addAction(damage); + return 1; +} + +int ActionStack::AddNextGamePhase(){ + if (getNext(NULL,NOT_RESOLVED)) return 0; + NextGamePhase * next = NEW NextGamePhase(mCount); + addAction(next); + int playerId = 0; + if (game->currentActionPlayer == game->players[1]) playerId = 1; + interruptDecision[playerId] = 1; + return 1; +} + +int ActionStack::setIsInterrupting(Player * player){ + if (player == game->players[0]){ + interruptDecision[0] = -1; + }else{ + interruptDecision[1] = -1; + } + game->isInterrupting = player; + askIfWishesToInterrupt = NULL; + return 1; +} + + +int ActionStack::addAction(Interruptible * action){ + for (int i=0; i<2; i++){ + interruptDecision[i] = 0; + } + Add(action); + return 1; +} + +int ActionStack::addSpell(MTGCardInstance * _source, Targetable * _targets[], int _nbtargets, ManaCost * mana){ +#if defined (WIN32) || defined (LINUX) + char buf[4096], *p = buf; + sprintf(buf, "Add spell\n"); + OutputDebugString(buf); +#endif + Spell * spell = NEW Spell(mCount,_source,_targets,_nbtargets, mana); + return addAction(spell); +} + + +Interruptible * ActionStack::_(int id){ + if (id < 0) id = mCount + id; + if (id > mCount -1) return NULL; + return (Interruptible *)mObjects[id]; +} + +ActionStack::ActionStack(int id, GameObserver* _game):GuiLayer(id, _game){ + for (int i=0; i<2; i++){ + interruptDecision[i] = 0; + } + askIfWishesToInterrupt = NULL; + timer = -1; + currentState = -1; + mode = ACTIONSTACK_STANDARD; + checked = 0; + +} + +int ActionStack::has(Interruptible * action){ + for (int i = 0; i < mCount ; i++){ + if (mObjects[i] == action) return 1; + } + return 0; +} + +int ActionStack::resolve(){ + Interruptible * action = getLatest(NOT_RESOLVED); + + if (!action) + return 0; + + + if (action->resolve()){ + action->state = RESOLVED_OK; + }else{ + action->state = RESOLVED_NOK; + } + if (action->type == ACTION_DAMAGE) ((Damage * )action)->target->afterDamage(); + if (action->type == ACTION_DAMAGES){ + DamageStack * ds = (DamageStack *) action; + for (int i = 0; i < ds->mCount; i++){ + Damage * damage = ((Damage *) ds->mObjects[i]); + damage->state = ds->state; + } + unpackDamageStack(ds); + ds->mCount = 0; + } + + if (!getNext(NULL,NOT_RESOLVED)){ + for (int i = 0; i< 2 ; i++){ + interruptDecision[i] = 0; + } + }else{ + for (int i = 0; i< 2 ; i++){ + if (interruptDecision[i] != 2) interruptDecision[i] = 0; + } + } + + return 1; + +} + +Interruptible * ActionStack::getPrevious(Interruptible * next, int type, int state, int display){ + int n = getPreviousIndex( next, type, state, display); + if (n==-1) return NULL; + return ((Interruptible *) mObjects[n]); +} + +int ActionStack::getPreviousIndex(Interruptible * next, int type, int state, int display){ + int found = 0; + if (!next) found = 1; + for (int i = mCount -1; i >= 0 ; i--){ + Interruptible * current = (Interruptible *)mObjects[i]; + if (found && (type == 0 || current->type == type) && (state == 0 || current->state == state) && (display == -1 || current->display == display)){ + return i; + } + if (current == next) found = 1; + } + if (!found) return getPreviousIndex(NULL,type, state, display); + return -1; +} + +int ActionStack::count( int type, int state, int display){ + int result = 0; + for (int i = 0; i < mCount ; i++){ + Interruptible * current = (Interruptible *)mObjects[i]; + if((type == 0 || current->type == type) && (state == 0 || current->state == state) && (display == -1 || current->display == display)){ + result++; + } + } + return result; +} + +Interruptible * ActionStack::getNext(Interruptible * previous, int type, int state, int display){ + int n = getNextIndex( previous, type, state, display); + if (n==-1) return NULL; + return ((Interruptible *) mObjects[n]); +} + +int ActionStack::getNextIndex(Interruptible * previous, int type, int state, int display){ + int found = 0; + if (!previous) found = 1; + for (int i = 0; i < mCount ; i++){ + Interruptible * current = (Interruptible *)mObjects[i]; + if (found && (type == 0 || current->type == type) && (state == 0 || current->state == state) && (display == -1 || current->display == display)){ + return i; + } + if (current == previous) found = 1; + } + if (!found) return getNextIndex(NULL,type, state, display); + return -1; +} + + +Interruptible * ActionStack::getLatest(int state){ + for (int i = mCount-1; i >=0; i--){ + Interruptible * action = ((Interruptible *)mObjects[i]); + if (action->state == state) return action; + } + return NULL; +} + +void ActionStack::unpackDamageStack(DamageStack * ds){ + for (int j = 0; j < ds->mCount; j++){ + Damage * damage = ((Damage *)ds->mObjects[j]); + Add(damage); + } +} + +void ActionStack::unpackDamageStacks(){ + for (int i = mCount-1; i >=0; i--){ + Interruptible * action = ((Interruptible *)mObjects[i]); + if (action->type == ACTION_DAMAGES){ + DamageStack * ds = (DamageStack *) action; + unpackDamageStack(ds); + } + } +} + +void ActionStack::repackDamageStacks(){ + for (int i = mCount-1; i >=0; i--){ + Interruptible * action = ((Interruptible *)mObjects[i]); + if (action->type == ACTION_DAMAGE){ + Damage * damage = (Damage *) action; + for (int j = 0; j < mCount; j++){ + Interruptible * action2 = ((Interruptible *)mObjects[j]); + if (action->type == ACTION_DAMAGES){ + DamageStack * ds = (DamageStack *) action2; + for (int k = 0; k< ds->mCount; k++){ + Damage * dsdamage = ((Damage *)ds->mObjects[k]); + if (dsdamage==damage) Remove(damage); + } + } + } + } + } +} + +void ActionStack::Update(float dt){ + askIfWishesToInterrupt = NULL; + //modal = 0; + GameObserver * game = GameObserver::GetInstance(); + TargetChooser * tc = game->getCurrentTargetChooser(); + int newState = game->getCurrentGamePhase(); + currentState = newState; + + //Select Stack's display mode + if (mode==ACTIONSTACK_STANDARD && tc && !checked){ + checked = 1; + unpackDamageStacks(); + for (int i = 0; i < mCount ; i++){ + Interruptible * current = (Interruptible *)mObjects[i]; + if (tc->canTarget(current)){ + if (mObjects[mCurr]) mObjects[mCurr]->Leaving(PSP_CTRL_UP); + current->display = 1; + mCurr = i; + mObjects[mCurr]->Entering(); + mode=ACTIONSTACK_TARGET; + modal = 1; + }else{ + current->display = 0; + } + } + if (mode != ACTIONSTACK_TARGET){ + repackDamageStacks(); + } + }else if (mode==ACTIONSTACK_TARGET && !tc){ + mode = ACTIONSTACK_STANDARD; + checked = 0; + repackDamageStacks(); + } + + if (mode == ACTIONSTACK_STANDARD){ + modal = 0; + if (getLatest(NOT_RESOLVED)){ + int currentPlayerId = 0; + int otherPlayerId = 1; + if (game->currentPlayer != game->players[0]){ + currentPlayerId = 1; + otherPlayerId = 0; + } + if (interruptDecision[currentPlayerId] == 0){ + askIfWishesToInterrupt = game->players[currentPlayerId]; + game->isInterrupting = game->players[currentPlayerId]; + modal = 1; + }else if (interruptDecision[currentPlayerId] == -1){ + game->isInterrupting = game->players[currentPlayerId]; + + }else{ + if (interruptDecision[otherPlayerId] == 0){ + askIfWishesToInterrupt = game->players[otherPlayerId]; + game->isInterrupting = game->players[otherPlayerId]; + modal = 1; + }else if (interruptDecision[otherPlayerId] == -1){ + game->isInterrupting = game->players[otherPlayerId]; + }else{ + resolve(); + } + } + } + }else if (mode == ACTIONSTACK_TARGET){ + GuiLayer::Update(dt); + } +} + +void ActionStack::cancelInterruptOffer(int cancelMode){ + if (askIfWishesToInterrupt == game->players[0]){ + interruptDecision[0] = cancelMode; + }else{ + interruptDecision[1] = cancelMode; + } + askIfWishesToInterrupt = NULL; + game->isInterrupting = NULL; + timer = -1; +} + +void ActionStack::endOfInterruption(){ + if (game->isInterrupting == game->players[0]){ + interruptDecision[0] = 0; + }else{ + interruptDecision[1] = 0; + } + game->isInterrupting = NULL; +} + + +void ActionStack::CheckUserInput(float dt){ + if (mode == ACTIONSTACK_STANDARD){ + if (askIfWishesToInterrupt){ + if (timer < 0) timer = 300; + if (mEngine->GetButtonClick(PSP_CTRL_CROSS)){ + setIsInterrupting(askIfWishesToInterrupt); + }else if (mEngine->GetButtonClick(PSP_CTRL_CIRCLE) ||mEngine->GetButtonClick(PSP_CTRL_RTRIGGER) ){ + cancelInterruptOffer(); + }else if (mEngine->GetButtonClick(PSP_CTRL_SQUARE)){ + cancelInterruptOffer(2); + }else{ + timer --; + if (timer < 0){ + cancelInterruptOffer(); + } + } + }else if (game->isInterrupting){ + if (mEngine->GetButtonClick(PSP_CTRL_CROSS)){ + endOfInterruption(); + } + } + }else if (mode == ACTIONSTACK_TARGET){ + if (modal){ + if (mEngine->GetButtonState(PSP_CTRL_UP)){ + if (KeyRepeated(PSP_CTRL_UP, dt)) + { + if( mObjects[mCurr]){ + int n = getPreviousIndex(((Interruptible *) mObjects[mCurr]), 0, 0, 1); + if (n != -1 && n != mCurr && mObjects[mCurr]->Leaving(PSP_CTRL_UP)) + { + mCurr = n; + mObjects[mCurr]->Entering(); +#if defined (WIN32) || defined (LINUX) + char buf[4096]; + sprintf(buf, "Stack UP TO mCurr = %i\n", mCurr); + OutputDebugString(buf); +#endif + } + } + } + }else if (mEngine->GetButtonState(PSP_CTRL_DOWN)){ + if (KeyRepeated(PSP_CTRL_DOWN, dt)) + { + if( mObjects[mCurr]){ + int n = getNextIndex(((Interruptible *) mObjects[mCurr]), 0, 0, 1); + if (n!= -1 && n != mCurr && mObjects[mCurr]->Leaving(PSP_CTRL_DOWN)) + { + mCurr = n; + mObjects[mCurr]->Entering(); +#if defined (WIN32) || defined (LINUX) + char buf[4096]; + sprintf(buf, "Stack DOWN TO mCurr = %i\n", mCurr); + OutputDebugString(buf); +#endif + } + } + } + }else if (mEngine->GetButtonClick(PSP_CTRL_CIRCLE)){ +#if defined (WIN32) || defined (LINUX) + char buf[4096]; + sprintf(buf, "Stack CLIKED mCurr = %i\n", mCurr); + OutputDebugString(buf); +#endif + game->stackObjectClicked(((Interruptible *) mObjects[mCurr])); + } + } + if (mEngine->GetButtonClick(PSP_CTRL_TRIANGLE)){ + if (modal) {modal = 0;} else {modal = 1;} + } + } +} + + + + +int ActionStack::CombatDamages(){ + CombatDamages(1); + CombatDamages(0); + return 1; +} + +int ActionStack::CombatDamages(int strike){ + DamageStack * damages = NEW DamageStack(mCount,game); + int damageitems = damages->CombatDamages(strike); + if (damageitems){ + addAction(damages); + }else{ + delete damages; + } + return damageitems; +} + +//Cleans history of last turn +int ActionStack::garbageCollect(){ + for (int i=mCount-1;i>=0; i--){ + Interruptible * current = ((Interruptible *)mObjects[i]); + if (current->state != NOT_RESOLVED){ + mObjects[i] = mObjects[mCount-1]; + mCount--; + delete current; + } + } + return 1; +} + +void ActionStack::Fizzle(Interruptible * action){ + if (action->type == ACTION_SPELL){ + Spell * spell = (Spell *) action; + spell->source->controller()->game->putInGraveyard(spell->source); + } + action->state = RESOLVED_NOK; +} + +void ActionStack::Render(){ + int x0 = 250; + int y0 = 30; + int width = 200; + int height = 90; + int currenty = y0 + 5 ; + + if (mode == ACTIONSTACK_STANDARD){ + if (!askIfWishesToInterrupt || !askIfWishesToInterrupt->displayStack()) return; + + + for (int i=0;istate==NOT_RESOLVED) height += current->mHeight; + } + + JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); + mFont->SetBase(0); + mFont->SetScale(0.75); + + JRenderer * renderer = JRenderer::GetInstance(); + + //JQuad * back = GameApp::CommonRes->GetQuad("interrupt"); + //float xScale = width / back->mWidth; + //float yScale = height / back->mHeight; + renderer->FillRoundRect(x0 + 16 ,y0 + 16 ,width +2 ,height +2 , 10, ARGB(128,0,0,0)); + renderer->FillRoundRect(x0 - 5 ,y0 - 5 ,width + 2,height +2 , 10, ARGB(200,0,0,0)); + //renderer->RenderQuad(back,x0,y0,0,xScale, yScale); + renderer->DrawRoundRect(x0 - 5 ,y0 - 5 ,width + 2,height +2 , 10, ARGB(255,255,255,255)); + + + for (int i=0;istate==NOT_RESOLVED){ + current->x = x0 + 5; + if (i != mCount -1){ + current->y = currenty; + currenty += current->mHeight; + }else{ + current->y = currenty + 40 ; + currenty += current->mHeight + 40; + } + current->Render(); + } + } + + char buffer[200]; + sprintf(buffer, "interrupt ? %i", timer/100); + mFont->DrawString(buffer, x0 + 5 , currenty - 40 - ((Interruptible *)mObjects[mCount-1])->mHeight); + + if (mCount > 1){ + sprintf(buffer, "X Interrupt - 0 No - [] No to All"); + }else{ + sprintf(buffer, "X Interrupt - 0 No"); + } + mFont->DrawString(buffer, x0 + 5 , currenty); + }else if (mode == ACTIONSTACK_TARGET && modal){ + for (int i=0;idisplay) height += current->mHeight; + } + + JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); + mFont->SetBase(0); + mFont->SetScale(0.75); + + JRenderer * renderer = JRenderer::GetInstance(); + renderer->FillRect(x0 ,y0 , width ,height , ARGB(200,0,0,0)); + renderer->DrawRect(x0 - 1 ,y0 - 1 ,width + 2 ,height +2 , ARGB(255,255,255,255)); + + + for (int i=0;idisplay){ + ((Interruptible *)mObjects[i])->x = x0 + 5; + if (i != mCount -1){ + ((Interruptible *)mObjects[i])->y = currenty; + currenty += ((Interruptible *)mObjects[i])->mHeight; + }else{ + ((Interruptible *)mObjects[i])->y = currenty + 40 ; + currenty += ((Interruptible *)mObjects[i])->mHeight + 40; + } + mObjects[i]->Render(); + } + } + } +} diff --git a/projects/mtg/src/Blocker.cpp b/projects/mtg/src/Blocker.cpp index 3320f659c..8d75fb60a 100644 --- a/projects/mtg/src/Blocker.cpp +++ b/projects/mtg/src/Blocker.cpp @@ -1,117 +1,117 @@ -#include "../include/debug.h" -#include "../include/Blocker.h" - -Blocker::Blocker(int id, MTGCardInstance * card):MTGAbility(id, card){ - init ( NEW ManaCost()); -} - -Blocker::Blocker(int id, MTGCardInstance * card, ManaCost * _cost):MTGAbility(id, card){ - init(_cost); -} - -Blocker::Blocker(int id, MTGCardInstance * card, MTGCardInstance *_target, ManaCost * _cost):MTGAbility(id, card,_target){ - init(_cost); -} - -Blocker::~Blocker(){ - delete manaCost; -} - -void Blocker::init(ManaCost * _cost){ - currentPhase = -1; - manaCost = _cost; -} - - -//Default behaviour for blockers : they block the card they're attached to -void Blocker::Update(float dt){ -game = GameObserver::GetInstance(); - int newPhase = game->getCurrentGamePhase(); - if (newPhase != currentPhase){ - MTGCardInstance * _target; - if (target){ - _target = (MTGCardInstance *) target; - }else{ - _target = source; - } - _target->getBlockers()->Add(this); -#if defined (WIN32) || defined (LINUX) -char buf[4096]; -sprintf(buf, "Adding Blocker to %s \n", _target->model->getName()); -OutputDebugString(buf); -#endif - } - currentPhase = newPhase; -} - -int Blocker::destroy(){ - MTGCardInstance * _target; - if (target){ - _target = (MTGCardInstance *) target; - }else{ - _target = source; - } - _target->getBlockers()->Remove(this); - return 1; -} - -Blockers::Blockers(){ - init(); -} - - - -int Blockers::init(){ - cursor = -1; - - for (int i=0; i< MAX_BLOCKERS ; i++){ - blockers[i] = 0; - } - - return 1; -} - -int Blockers::Add (Blocker * ability){ - game = GameObserver::GetInstance(); - int index = game->mLayers->actionLayer()->getIndexOf(ability); - blockers[index] = 1; - return index; -} -int Blockers::Remove (Blocker * ability){ - game = GameObserver::GetInstance(); - int index = game->mLayers->actionLayer()->getIndexOf(ability); - blockers[index] = 0; - return index; -} - -int Blockers::rewind(){ - cursor = -1; - return 1; -} - -Blocker * Blockers::next(){ - cursor++; - game = GameObserver::GetInstance(); - while (blockers[cursor] == 0){ - cursor ++; - if (cursor == MAX_BLOCKERS){ - cursor = -1; - return NULL; - } - } - return (Blocker *) (game->mLayers->actionLayer()->getByIndex(cursor)); -} - - - -int Blockers::isEmpty(){ - for (int i=0; i< MAX_BLOCKERS ; i++){ - if (blockers[i]) - return 0; - } - return 1; -} - -Blockers::~Blockers(){ - -} \ No newline at end of file +#include "../include/debug.h" +#include "../include/Blocker.h" + +Blocker::Blocker(int id, MTGCardInstance * card):MTGAbility(id, card){ + init ( NEW ManaCost()); +} + +Blocker::Blocker(int id, MTGCardInstance * card, ManaCost * _cost):MTGAbility(id, card){ + init(_cost); +} + +Blocker::Blocker(int id, MTGCardInstance * card, MTGCardInstance *_target, ManaCost * _cost):MTGAbility(id, card,_target){ + init(_cost); +} + +Blocker::~Blocker(){ + delete manaCost; +} + +void Blocker::init(ManaCost * _cost){ + currentPhase = -1; + manaCost = _cost; +} + + +//Default behaviour for blockers : they block the card they're attached to +void Blocker::Update(float dt){ + game = GameObserver::GetInstance(); + int newPhase = game->getCurrentGamePhase(); + if (newPhase != currentPhase){ + MTGCardInstance * _target; + if (target){ + _target = (MTGCardInstance *) target; + }else{ + _target = source; + } + _target->getBlockers()->Add(this); +#if defined (WIN32) || defined (LINUX) + char buf[4096]; + sprintf(buf, "Adding Blocker to %s \n", _target->model->getName()); + OutputDebugString(buf); +#endif + } + currentPhase = newPhase; +} + +int Blocker::destroy(){ + MTGCardInstance * _target; + if (target){ + _target = (MTGCardInstance *) target; + }else{ + _target = source; + } + _target->getBlockers()->Remove(this); + return 1; +} + +Blockers::Blockers(){ + init(); +} + + + +int Blockers::init(){ + cursor = -1; + + for (int i=0; i< MAX_BLOCKERS ; i++){ + blockers[i] = 0; + } + + return 1; +} + +int Blockers::Add (Blocker * ability){ + game = GameObserver::GetInstance(); + int index = game->mLayers->actionLayer()->getIndexOf(ability); + blockers[index] = 1; + return index; +} +int Blockers::Remove (Blocker * ability){ + game = GameObserver::GetInstance(); + int index = game->mLayers->actionLayer()->getIndexOf(ability); + blockers[index] = 0; + return index; +} + +int Blockers::rewind(){ + cursor = -1; + return 1; +} + +Blocker * Blockers::next(){ + cursor++; + game = GameObserver::GetInstance(); + while (blockers[cursor] == 0){ + cursor ++; + if (cursor == MAX_BLOCKERS){ + cursor = -1; + return NULL; + } + } + return (Blocker *) (game->mLayers->actionLayer()->getByIndex(cursor)); +} + + + +int Blockers::isEmpty(){ + for (int i=0; i< MAX_BLOCKERS ; i++){ + if (blockers[i]) + return 0; + } + return 1; +} + +Blockers::~Blockers(){ + +} diff --git a/projects/mtg/src/CardDescriptor.cpp b/projects/mtg/src/CardDescriptor.cpp index 0c665f2bd..56aaffea5 100644 --- a/projects/mtg/src/CardDescriptor.cpp +++ b/projects/mtg/src/CardDescriptor.cpp @@ -1,131 +1,131 @@ -#include "../include/debug.h" -#include "../include/CardDescriptor.h" - -CardDescriptor::CardDescriptor(): MTGCardInstance(){ - init(); - mode = CD_AND; -} - -int CardDescriptor::init(){ - return MTGCardInstance::init(); -} - -MTGCardInstance * CardDescriptor::match_or(MTGCardInstance * card){ - int found = 1; - for (int i = 0; i< nb_types; i++){ - found = 0; - if (card->hasSubtype(types[i])){ - found = 1; - break; - } - } - if (!found) return NULL; - - for (int i = 0; i< MTG_NB_COLORS; i++){ - found = 0; - if (colors[i] == 1 && card->hasColor(i)){ - found = 1; - break; - } - } - if (!found) return NULL; - return card; -} - -MTGCardInstance * CardDescriptor::match_and(MTGCardInstance * card){ -#ifdef WIN32 - OutputDebugString("Match AND\n"); -#endif - - MTGCardInstance * match = card; - for (int i = 0; i< nb_types; i++){ - - if (!card->hasSubtype(types[i])){ -#ifdef WIN32 - OutputDebugString(card->name.c_str()); - OutputDebugString("Subtype No Match\n"); -#endif - match = NULL; - } - } - for (int i = 0; i< MTG_NB_COLORS; i++){ - if ((colors[i] == 1 && !card->hasColor(i))||(colors[i] == -1 && card->hasColor(i))){ - match = NULL; -#ifdef WIN32 - OutputDebugString(card->name.c_str()); - OutputDebugString("Color No Match\n"); -#endif - } - } - return match; -} - -MTGCardInstance * CardDescriptor::match(MTGCardInstance * card){ - - MTGCardInstance * match = card; - - if (mode == CD_AND){ - match = match_and(card); - }else{ - match=match_or(card); - } - - //Abilities - for (int j = 0; j < NB_BASIC_ABILITIES; j++){ - if ((basicAbilities[j] == 1 && !card->basicAbilities[j]) || (basicAbilities[j] == -1 && card->basicAbilities[j])){ - match = NULL; - } - } - - if ((tapped == -1 && card->isTapped()) || (tapped == 1 && !card->isTapped())){ - match = NULL; - } - - if (attacker == 1){ - if ((int)defenser == 1){ - if (!card->attacker && !card->defenser) match = NULL; - }else{ - if (!card->attacker) match = NULL; - } - }else if (attacker == -1){ - if ((int)defenser == -1){ - if (card->attacker || card->defenser) match = NULL; - }else{ - if (card->attacker) match = NULL; - } - }else{ - if ((int)defenser == -1){ - if (card->defenser) match = NULL; - }else if ((int)defenser == 1){ - if (!card->defenser) match = NULL; - }else{ - // we don't care about the attack/blocker state - } - } - - - return match; -} - -MTGCardInstance * CardDescriptor::match(MTGGameZone * zone){ - return (nextmatch(zone, NULL)); -} - -MTGCardInstance * CardDescriptor::nextmatch(MTGGameZone * zone, MTGCardInstance * previous){ - int found = 0; - if (NULL == previous) found = 1; - for(int i=0; i < zone->nb_cards; i++){ - if(found && match(zone->cards[i])){ - #if defined (WIN32) || defined (LINUX) -char buf[4096]; -sprintf(buf,"Card Descriptor MATCH!: %s \n" ,(zone->cards[i])->getName()); -OutputDebugString(buf); -#endif - return zone->cards[i]; - } - if (zone->cards[i] == previous){ - found = 1; - } - } - return NULL; -} +#include "../include/debug.h" +#include "../include/CardDescriptor.h" + +CardDescriptor::CardDescriptor(): MTGCardInstance(){ + init(); + mode = CD_AND; +} + +int CardDescriptor::init(){ + return MTGCardInstance::init(); +} + +MTGCardInstance * CardDescriptor::match_or(MTGCardInstance * card){ + int found = 1; + for (int i = 0; i< nb_types; i++){ + found = 0; + if (card->hasSubtype(types[i])){ + found = 1; + break; + } + } + if (!found) return NULL; + + for (int i = 0; i< MTG_NB_COLORS; i++){ + found = 0; + if (colors[i] == 1 && card->hasColor(i)){ + found = 1; + break; + } + } + if (!found) return NULL; + return card; +} + +MTGCardInstance * CardDescriptor::match_and(MTGCardInstance * card){ +#ifdef WIN32 + OutputDebugString("Match AND\n"); +#endif + + MTGCardInstance * match = card; + for (int i = 0; i< nb_types; i++){ + + if (!card->hasSubtype(types[i])){ +#ifdef WIN32 + OutputDebugString(card->name.c_str()); + OutputDebugString("Subtype No Match\n"); +#endif + match = NULL; + } + } + for (int i = 0; i< MTG_NB_COLORS; i++){ + if ((colors[i] == 1 && !card->hasColor(i))||(colors[i] == -1 && card->hasColor(i))){ + match = NULL; +#ifdef WIN32 + OutputDebugString(card->name.c_str()); + OutputDebugString("Color No Match\n"); +#endif + } + } + return match; +} + +MTGCardInstance * CardDescriptor::match(MTGCardInstance * card){ + + MTGCardInstance * match = card; + + if (mode == CD_AND){ + match = match_and(card); + }else{ + match=match_or(card); + } + + //Abilities + for (int j = 0; j < NB_BASIC_ABILITIES; j++){ + if ((basicAbilities[j] == 1 && !card->basicAbilities[j]) || (basicAbilities[j] == -1 && card->basicAbilities[j])){ + match = NULL; + } + } + + if ((tapped == -1 && card->isTapped()) || (tapped == 1 && !card->isTapped())){ + match = NULL; + } + + if (attacker == 1){ + if ((int)defenser == 1){ + if (!card->attacker && !card->defenser) match = NULL; + }else{ + if (!card->attacker) match = NULL; + } + }else if (attacker == -1){ + if ((int)defenser == -1){ + if (card->attacker || card->defenser) match = NULL; + }else{ + if (card->attacker) match = NULL; + } + }else{ + if ((int)defenser == -1){ + if (card->defenser) match = NULL; + }else if ((int)defenser == 1){ + if (!card->defenser) match = NULL; + }else{ + // we don't care about the attack/blocker state + } + } + + + return match; +} + +MTGCardInstance * CardDescriptor::match(MTGGameZone * zone){ + return (nextmatch(zone, NULL)); +} + +MTGCardInstance * CardDescriptor::nextmatch(MTGGameZone * zone, MTGCardInstance * previous){ + int found = 0; + if (NULL == previous) found = 1; + for(int i=0; i < zone->nb_cards; i++){ + if(found && match(zone->cards[i])){ +#if defined (WIN32) || defined (LINUX) + char buf[4096]; + sprintf(buf,"Card Descriptor MATCH!: %s \n" ,(zone->cards[i])->getName()); + OutputDebugString(buf); +#endif + return zone->cards[i]; + } + if (zone->cards[i] == previous){ + found = 1; + } + } + return NULL; +} diff --git a/projects/mtg/src/CardDisplay.cpp b/projects/mtg/src/CardDisplay.cpp index ad6fcb9df..b53fba7b4 100644 --- a/projects/mtg/src/CardDisplay.cpp +++ b/projects/mtg/src/CardDisplay.cpp @@ -1,156 +1,156 @@ -#include "../include/debug.h" -#include "../include/CardDisplay.h" -#include "../include/CardGui.h" -#include "../include/TargetChooser.h" -#include "../include/MTGGameZones.h" - -CardDisplay::CardDisplay():PlayGuiObjectController(0, GameObserver::GetInstance()){ - tc= NULL; - listener = NULL; - nb_displayed_items = 7; - start_item = 0; - x= 0; - y= 0; -} - -CardDisplay::CardDisplay(int id, GameObserver* _game, int _x, int _y, JGuiListener * _listener, TargetChooser * _tc, int _nb_displayed_items ):PlayGuiObjectController(id, _game), x(_x), y(_y){ - tc= _tc; - listener = _listener; - nb_displayed_items = _nb_displayed_items; - start_item = 0; -} - - -void CardDisplay::AddCard(MTGCardInstance * _card){ - CardGui * card = NEW CardGui(mCount, _card, 40, x + 5 + (mCount - start_item) * 30, y + 5, (mCount == 0)); - Add(card); -} - - -void CardDisplay::init(MTGGameZone * zone){ - resetObjects(); - start_item = 0; - for (int i= 0; i< zone->nb_cards; i++){ - AddCard(zone->cards[i]); - } -} - -void CardDisplay::rotateLeft(){ - if (start_item==0) return; - for (int i= 0; ix+=30; - } - start_item --; -} - -void CardDisplay::rotateRight(){ - if (start_item==mCount-1) return; - for (int i= 0; ix-=30; - } - start_item ++; -} - - -void CardDisplay::CheckUserInput(float dt){ - if (mEngine->GetButtonClick(PSP_CTRL_CROSS)) - { - if (listener != NULL) - { - listener->ButtonPressed(mId, 0); - return; - } - } - - - if (!mCount) - return; +#include "../include/debug.h" +#include "../include/CardDisplay.h" +#include "../include/CardGui.h" +#include "../include/TargetChooser.h" +#include "../include/MTGGameZones.h" - if (mEngine->GetButtonClick(mActionButton)) - { - if (mObjects[mCurr] && mObjects[mCurr]->ButtonPressed()){ - CardGui * cardg = (CardGui *)mObjects[mCurr]; - if (tc) - { - tc->toggleTarget(cardg->card); - return; - }else{ - if (game) game->ButtonPressed(mId, cardg); - return; - } - } - } - +CardDisplay::CardDisplay():PlayGuiObjectController(0, GameObserver::GetInstance()){ + tc= NULL; + listener = NULL; + nb_displayed_items = 7; + start_item = 0; + x= 0; + y= 0; +} - if (mEngine->GetButtonState(PSP_CTRL_LEFT)) - { - if (KeyRepeated(PSP_CTRL_LEFT, dt)) - { - int n = mCurr; - n--; - if (nLeaving(PSP_CTRL_LEFT)){ - mCurr = n; - mObjects[mCurr]->Entering(); - } - } - } - else if (mEngine->GetButtonState(PSP_CTRL_RIGHT)) - { - if (KeyRepeated(PSP_CTRL_RIGHT, dt)) - { - int n = mCurr; - n++; - if (n>= mCount){n = mCount-1;} - if (n>= start_item + nb_displayed_items){ - rotateRight(); - } - if (n != mCurr && mObjects[mCurr] != NULL && mObjects[mCurr]->Leaving(PSP_CTRL_RIGHT)){ - mCurr = n; - mObjects[mCurr]->Entering(); - } - } - } +CardDisplay::CardDisplay(int id, GameObserver* _game, int _x, int _y, JGuiListener * _listener, TargetChooser * _tc, int _nb_displayed_items ):PlayGuiObjectController(id, _game), x(_x), y(_y){ + tc= _tc; + listener = _listener; + nb_displayed_items = _nb_displayed_items; + start_item = 0; +} - else{ - mLastKey = 0; + +void CardDisplay::AddCard(MTGCardInstance * _card){ + CardGui * card = NEW CardGui(mCount, _card, 40, x + 5 + (mCount - start_item) * 30, y + 5, (mCount == 0)); + Add(card); +} + + +void CardDisplay::init(MTGGameZone * zone){ + resetObjects(); + start_item = 0; + for (int i= 0; i< zone->nb_cards; i++){ + AddCard(zone->cards[i]); + } +} + +void CardDisplay::rotateLeft(){ + if (start_item==0) return; + for (int i= 0; ix+=30; + } + start_item --; +} + +void CardDisplay::rotateRight(){ + if (start_item==mCount-1) return; + for (int i= 0; ix-=30; + } + start_item ++; +} + + +void CardDisplay::CheckUserInput(float dt){ + if (mEngine->GetButtonClick(PSP_CTRL_CROSS)) + { + if (listener != NULL) + { + listener->ButtonPressed(mId, 0); + return; } - -} - - -void CardDisplay::Render(){ - - JRenderer * r = JRenderer::GetInstance(); - r->DrawRect(x,y,nb_displayed_items * 30 + 20, 50, ARGB(255,255,255,255)); -if (!mCount) return; - for (int i = start_item; i< start_item + nb_displayed_items && i < mCount; i++){ - if (mObjects[i]){ - mObjects[i]->Render(); - if (tc){ - CardGui * cardg = (CardGui *)mObjects[i]; - if( tc->alreadyHasTarget(cardg->card)){ - r->DrawCircle(cardg->x + 5, cardg->y+5,5, ARGB(255,255,0,0)); - }else if (!tc->canTarget(cardg->card)){ - r->FillRect(cardg->x,cardg->y,30,40,ARGB(200,0,0,0)); - } - } - } - } - if (mObjects[mCurr]){ - mObjects[mCurr]->Render(); - } -} - -DefaultTargetDisplay::DefaultTargetDisplay(int id, GameObserver* _game, int _x, int _y,JGuiListener * _listener, int _nb_displayed_items ):CardDisplay(id, _game, _x, _y, _listener, NULL, _nb_displayed_items ){ - tc = NEW TargetChooser(); -} - -DefaultTargetDisplay::~DefaultTargetDisplay(){ - SAFE_DELETE(tc); -} \ No newline at end of file + } + + + if (!mCount) + return; + + if (mEngine->GetButtonClick(mActionButton)) + { + if (mObjects[mCurr] && mObjects[mCurr]->ButtonPressed()){ + CardGui * cardg = (CardGui *)mObjects[mCurr]; + if (tc) + { + tc->toggleTarget(cardg->card); + return; + }else{ + if (game) game->ButtonPressed(mId, cardg); + return; + } + } + } + + + if (mEngine->GetButtonState(PSP_CTRL_LEFT)) + { + if (KeyRepeated(PSP_CTRL_LEFT, dt)) + { + int n = mCurr; + n--; + if (nLeaving(PSP_CTRL_LEFT)){ + mCurr = n; + mObjects[mCurr]->Entering(); + } + } + } + else if (mEngine->GetButtonState(PSP_CTRL_RIGHT)) + { + if (KeyRepeated(PSP_CTRL_RIGHT, dt)) + { + int n = mCurr; + n++; + if (n>= mCount){n = mCount-1;} + if (n>= start_item + nb_displayed_items){ + rotateRight(); + } + if (n != mCurr && mObjects[mCurr] != NULL && mObjects[mCurr]->Leaving(PSP_CTRL_RIGHT)){ + mCurr = n; + mObjects[mCurr]->Entering(); + } + } + } + + else{ + mLastKey = 0; + } + +} + + +void CardDisplay::Render(){ + + JRenderer * r = JRenderer::GetInstance(); + r->DrawRect(x,y,nb_displayed_items * 30 + 20, 50, ARGB(255,255,255,255)); + if (!mCount) return; + for (int i = start_item; i< start_item + nb_displayed_items && i < mCount; i++){ + if (mObjects[i]){ + mObjects[i]->Render(); + if (tc){ + CardGui * cardg = (CardGui *)mObjects[i]; + if( tc->alreadyHasTarget(cardg->card)){ + r->DrawCircle(cardg->x + 5, cardg->y+5,5, ARGB(255,255,0,0)); + }else if (!tc->canTarget(cardg->card)){ + r->FillRect(cardg->x,cardg->y,30,40,ARGB(200,0,0,0)); + } + } + } + } + if (mObjects[mCurr]){ + mObjects[mCurr]->Render(); + } +} + +DefaultTargetDisplay::DefaultTargetDisplay(int id, GameObserver* _game, int _x, int _y,JGuiListener * _listener, int _nb_displayed_items ):CardDisplay(id, _game, _x, _y, _listener, NULL, _nb_displayed_items ){ + tc = NEW TargetChooser(); +} + +DefaultTargetDisplay::~DefaultTargetDisplay(){ + SAFE_DELETE(tc); +} diff --git a/projects/mtg/src/CardGui.cpp b/projects/mtg/src/CardGui.cpp index d17f3c002..32f48c045 100644 --- a/projects/mtg/src/CardGui.cpp +++ b/projects/mtg/src/CardGui.cpp @@ -1,318 +1,318 @@ -#include "../include/debug.h" -#include "../include/CardGui.h" -#include - -void CardGui::alternateRender(MTGCard * card, JLBFont * mFont, JQuad ** manaIcons, float x, float y, float rotation, float scale){ - JQuad * mIcons[7]; - if (!manaIcons){ - mIcons[MTG_COLOR_ARTIFACT] = GameApp::CommonRes->GetQuad("c_artifact"); - mIcons[MTG_COLOR_LAND] = GameApp::CommonRes->GetQuad("c_land"); - mIcons[MTG_COLOR_WHITE] = GameApp::CommonRes->GetQuad("c_white"); - mIcons[MTG_COLOR_RED] = GameApp::CommonRes->GetQuad("c_red"); - mIcons[MTG_COLOR_BLACK] = GameApp::CommonRes->GetQuad("c_black"); - mIcons[MTG_COLOR_BLUE] = GameApp::CommonRes->GetQuad("c_blue"); - mIcons[MTG_COLOR_GREEN] = GameApp::CommonRes->GetQuad("c_green"); - for (int i=0; i < 7; i++){ - mIcons[i]->SetHotSpot(16,16); - } - manaIcons = mIcons; - } - Vector2D v; - Vector2D points[4]; - PIXEL_TYPE bgcolor = ARGB(255,128,128,128); - PIXEL_TYPE bgcolor2 = ARGB(255,80,80,80); - char buf[25]; - int width = 200; - int height = 285; - - JRenderer * renderer = JRenderer::GetInstance(); - mFont->SetRotation(rotation); - mFont->SetScale(scale); - - int color = card->getColor(); - - points[0].x = -width/2; - points[0].y = -height/2 ; - points[1].x = width/2; - points[1].y = -height/2; - points[2].x = width/2; - points[2].y = height/2; - points[3].x = -width/2; - points[3].y = height/2; - - for (int i=0; i < 4; i++){ - points[i].x *= scale; - points[i].y *= scale; - points[i].Rotate(rotation); - } - - if (rotation == 0){ - renderer->FillRoundRect(x+points[0].x + 2 ,y+points[0].y +2 ,width*scale-8,height*scale-8,2,ARGB(255,_r[color],_g[color],_b[color])); - renderer->FillRect(x+points[0].x + 6 ,y+points[0].y + 6 ,width*scale-12,height*scale-12,bgcolor2); - }else{ - for (int i=0; i < 4; i++){ - renderer->DrawLine(x + points[i].x,y + points[i].y,x + points[(i+1)%4].x,y + points[(i+1)%4].y,bgcolor); - } - } - - - 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; - v.y = ((-height/2) + 20) * scale; - v.Rotate(rotation); - renderer->RenderQuad(manaIcons[i],x+v.x,y+v.y,rotation,0.5*scale, 0.5*scale); - nbicons++; - } - } - int cost = manacost->getCost(0); - if (cost !=0){ - v.x = (width/2 - 20 - 16*nbicons)*scale; - v.y = ((-height/2) + 14) * scale; - v.Rotate(rotation); - sprintf(buf,"%i",cost); - mFont->DrawString(buf,x+v.x,y+v.y); - } - - - if (!card->formattedTextInit){ - std::string s(card->getText()); - unsigned int found=s.find_first_of("{}"); - while (found!=string::npos) - { - s[found]='/'; - found=s.find_first_of("{}",found+1); - } - int len = 24; - while (s.length() > 0){ - int cut = s.find_first_of("., \t)", 0); - if (cut >= len || cut == -1){ - card->formattedText.push_back(s.substr(0,len)); - if ((signed int)s.length() > len){ - s = s.substr(len,s.length()-len); - }else{ - s = ""; - } - }else{ - int newcut = cut; - while (newcut < len && newcut != -1){ - cut = newcut; - newcut = s.find_first_of("., \t)", newcut + 1); - } - card->formattedText.push_back(s.substr(0,cut+1)); - if ((signed int)s.length() > cut+1){ - s = s.substr(cut+1,s.length()- cut - 1); - }else{ - s = ""; - } - } - } - card->formattedTextInit = 1; - } - - - - for (unsigned int i=0; i < card->formattedText.size(); i++){ - sprintf(buf, "%s", card->formattedText[i].c_str()); - v.x = (-width/2 + 12 )*scale; - v.y = ((-height/2) + 50 + 16*i) * scale; - v.Rotate(rotation); - mFont->DrawString(buf,x+v.x,y+v.y); - } - - - - v.x = ((-width/2)+10) * scale; - v.y = ((-height/2) + 25) * scale; - v.Rotate(rotation); - int over = strlen(card->getName()) - 23; - float multiply = 1.4; - if (over > 0){ - multiply = 1.1; - } - mFont->SetScale(scale * multiply); - mFont->SetColor(ARGB(255,_r[color],_g[color],_b[color])); - mFont->DrawString(card->getName(),x+v.x,y+v.y); - mFont->SetScale(scale); - mFont->SetColor(ARGB(255,255,255,255)); - - - if (card->isACreature()){ - v.x = (width/2-40) * scale; - v.y = (height/2-30) * scale; - v.Rotate(rotation); - sprintf(buf,"%i/%i",card->power,card->toughness); - mFont->DrawString(buf,x+v.x,y+v.y); - } - -} - - -CardGui::CardGui(int id, MTGCardInstance * _card, float desiredHeight,float _x, float _y, bool hasFocus): PlayGuiObject(id, desiredHeight, _x, _y, hasFocus){ - LOG("==Creating NEW CardGui Object. CardName:"); - LOG(_card->getName()); - - card = _card; - type = GUI_CARD; - - alpha = 255; - mParticleSys = NULL; - - if (card->hasColor(MTG_COLOR_RED)){ - mParticleSys = GameApp::Particles[3]; - }else if (card->hasColor(MTG_COLOR_BLUE)){ - mParticleSys = GameApp::Particles[1]; - }else if (card->hasColor(MTG_COLOR_GREEN)){ - mParticleSys = GameApp::Particles[2]; - }else if (card->hasColor(MTG_COLOR_BLACK)){ - mParticleSys = GameApp::Particles[4]; - }else if (card->hasColor(MTG_COLOR_WHITE)){ - mParticleSys = GameApp::Particles[0]; - }else{ - mParticleSys = GameApp::Particles[5]; - } - - LOG("==CardGui Object Creation Succesfull"); -} - - -void CardGui::Update(float dt){ - alpha = 255; - - if (card->changedZoneRecently > 0) alpha = 255.f - 255.f * card->changedZoneRecently; - if (mParticleSys && card->changedZoneRecently == 1.f){ - mParticleSys->MoveTo(x+15, y+2*mHeight/3); - mParticleSys->Fire(); - } - if (card->changedZoneRecently){ - if (mParticleSys) mParticleSys->Update(dt); - card->changedZoneRecently-= (5 *dt); - if (card->changedZoneRecently < 0){ - if (mParticleSys) mParticleSys->Stop(); - } - if (card->changedZoneRecently < -3){ - card->changedZoneRecently = 0; - mParticleSys = NULL; - } - } - PlayGuiObject::Update(dt); -} - -void CardGui::RenderBig(float xpos, float ypos){ - JRenderer * renderer = JRenderer::GetInstance(); - JQuad * quad = card->getQuad(); - if (xpos == -1){ - xpos = 300; - if (x > SCREEN_WIDTH / 2) - xpos = 10; - } - 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{ - MTGCard * mtgcard = card->model; - JLBFont * font = GameApp::CommonRes->GetJLBFont("graphics/magic"); - CardGui::alternateRender(mtgcard, font, NULL, xpos + 90 , ypos + 130, 0.0f,0.9f); - } -} - -void CardGui::Render(){ - - JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); - - JRenderer * renderer = JRenderer::GetInstance(); - JQuad * quad = card->getThumb(); - if (!quad || quad->mHeight * 2 < mHeight){ - JQuad * quad2 = card->getQuad(); - if (quad2) - quad = quad2; - } - - float tap = (float)(card->isTapped()); - float rotation = M_PI_2 * tap; - if (quad){ - float mScale = mHeight / quad->mHeight; - float myX = x + (quad->mHeight/2 * tap * mScale); - float myY = y+(quad->mWidth/2 * tap * mScale); - if (mHeight-defaultHeight){ - if (card->isTapped()){ - renderer->FillRect(myX + 1*(mHeight-defaultHeight) - quad->mHeight * mScale , myY + 1*(mHeight-defaultHeight) , quad->mHeight * mScale, quad->mWidth * mScale, ARGB(128,0,0,0)); - }else{ - renderer->FillRect(myX + 1*(mHeight-defaultHeight) , myY + 1*(mHeight-defaultHeight) , quad->mWidth * mScale, quad->mHeight * mScale, ARGB(128,0,0,0)); - } - } - - quad->SetColor(ARGB( alpha,255,255,255)); - GameObserver * game = GameObserver::GetInstance(); - TargetChooser * tc = NULL; - if (game) tc = game->getCurrentTargetChooser(); - if (tc){ - if (!tc->canTarget(card)){ - quad->SetColor(ARGB( alpha,50,50,50)); - } - } - renderer->RenderQuad(quad, myX , myY , rotation,mScale,mScale); - if (tc && tc->alreadyHasTarget(card)){ - if (card->isTapped()){ - renderer->FillRect(myX- quad->mHeight * mScale , myY , quad->mHeight * mScale, quad->mWidth * mScale, ARGB(128,255,0,0)); - }else{ - renderer->FillRect(myX , myY , quad->mWidth * mScale, quad->mHeight * mScale, ARGB(128,255,0,0)); - } - } - quad->SetColor(ARGB( alpha,255,255,255)); - }else{ - int color = card->getColor(); - float mScale = mHeight / 64; - float myX = x + (32 * tap * mScale); - float myY = y+(20 * tap * mScale); - - char buffer[200]; - sprintf(buffer, "%s",card->getName()); - mFont->SetColor(ARGB(255,_r[color],_g[color],_b[color])); - if (card->isTapped()){ - renderer->FillRect(myX - 64 * mScale , myY , 64 * mScale, 40 * mScale, ARGB(255,0,0,0)); - renderer->DrawRect(myX - 64 * mScale , myY , 64 * mScale, 40 * mScale, ARGB(255,_r[color],_g[color],_b[color])); - mFont->SetScale(0.20); - mFont->DrawString(buffer,myX - (64 * mScale)+4,myY + 1); - }else{ - renderer->FillRect(myX , myY , 40 * mScale, 64 * mScale, ARGB(255,0,0,0)); - renderer->DrawRect(myX , myY , 40 * mScale, 64 * mScale, ARGB(255,_r[color],_g[color],_b[color])); - mFont->SetScale(0.40); - mFont->DrawString(buffer,myX+4,myY + 1); - } - - - mFont->SetScale(1.0); - } - if (card->isACreature()){ - mFont->SetScale(0.75); - char buffer[200]; - sprintf(buffer, "%i/%i",card->power,card->life); - renderer->FillRect(x+2,y + mHeight - 12, 25 , 12 ,ARGB(128,0,0,0)); - mFont->SetColor(ARGB(255,255,255,255)); - mFont->DrawString(buffer,x+4,y + mHeight - 10); - } - - if (mParticleSys && card->changedZoneRecently > 0){ - renderer->SetTexBlend(BLEND_SRC_ALPHA, BLEND_ONE); - mParticleSys->Render(); - // set normal blending - renderer->SetTexBlend(BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA); - } -} - - - -CardGui::~CardGui(){ - LOG("==Destroying CardGui object"); - LOG(this->card->getName()); - LOG("==CardGui object destruction Successful"); -} - - - +#include "../include/debug.h" +#include "../include/CardGui.h" +#include + +void CardGui::alternateRender(MTGCard * card, JLBFont * mFont, JQuad ** manaIcons, float x, float y, float rotation, float scale){ + JQuad * mIcons[7]; + if (!manaIcons){ + mIcons[MTG_COLOR_ARTIFACT] = GameApp::CommonRes->GetQuad("c_artifact"); + mIcons[MTG_COLOR_LAND] = GameApp::CommonRes->GetQuad("c_land"); + mIcons[MTG_COLOR_WHITE] = GameApp::CommonRes->GetQuad("c_white"); + mIcons[MTG_COLOR_RED] = GameApp::CommonRes->GetQuad("c_red"); + mIcons[MTG_COLOR_BLACK] = GameApp::CommonRes->GetQuad("c_black"); + mIcons[MTG_COLOR_BLUE] = GameApp::CommonRes->GetQuad("c_blue"); + mIcons[MTG_COLOR_GREEN] = GameApp::CommonRes->GetQuad("c_green"); + for (int i=0; i < 7; i++){ + mIcons[i]->SetHotSpot(16,16); + } + manaIcons = mIcons; + } + Vector2D v; + Vector2D points[4]; + PIXEL_TYPE bgcolor = ARGB(255,128,128,128); + PIXEL_TYPE bgcolor2 = ARGB(255,80,80,80); + char buf[25]; + int width = 200; + int height = 285; + + JRenderer * renderer = JRenderer::GetInstance(); + mFont->SetRotation(rotation); + mFont->SetScale(scale); + + int color = card->getColor(); + + points[0].x = -width/2; + points[0].y = -height/2 ; + points[1].x = width/2; + points[1].y = -height/2; + points[2].x = width/2; + points[2].y = height/2; + points[3].x = -width/2; + points[3].y = height/2; + + for (int i=0; i < 4; i++){ + points[i].x *= scale; + points[i].y *= scale; + points[i].Rotate(rotation); + } + + if (rotation == 0){ + renderer->FillRoundRect(x+points[0].x + 2 ,y+points[0].y +2 ,width*scale-8,height*scale-8,2,ARGB(255,_r[color],_g[color],_b[color])); + renderer->FillRect(x+points[0].x + 6 ,y+points[0].y + 6 ,width*scale-12,height*scale-12,bgcolor2); + }else{ + for (int i=0; i < 4; i++){ + renderer->DrawLine(x + points[i].x,y + points[i].y,x + points[(i+1)%4].x,y + points[(i+1)%4].y,bgcolor); + } + } + + + 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; + v.y = ((-height/2) + 20) * scale; + v.Rotate(rotation); + renderer->RenderQuad(manaIcons[i],x+v.x,y+v.y,rotation,0.5*scale, 0.5*scale); + nbicons++; + } + } + int cost = manacost->getCost(0); + if (cost !=0){ + v.x = (width/2 - 20 - 16*nbicons)*scale; + v.y = ((-height/2) + 14) * scale; + v.Rotate(rotation); + sprintf(buf,"%i",cost); + mFont->DrawString(buf,x+v.x,y+v.y); + } + + + if (!card->formattedTextInit){ + std::string s(card->getText()); + unsigned int found=s.find_first_of("{}"); + while (found!=string::npos) + { + s[found]='/'; + found=s.find_first_of("{}",found+1); + } + int len = 24; + while (s.length() > 0){ + int cut = s.find_first_of("., \t)", 0); + if (cut >= len || cut == -1){ + card->formattedText.push_back(s.substr(0,len)); + if ((signed int)s.length() > len){ + s = s.substr(len,s.length()-len); + }else{ + s = ""; + } + }else{ + int newcut = cut; + while (newcut < len && newcut != -1){ + cut = newcut; + newcut = s.find_first_of("., \t)", newcut + 1); + } + card->formattedText.push_back(s.substr(0,cut+1)); + if ((signed int)s.length() > cut+1){ + s = s.substr(cut+1,s.length()- cut - 1); + }else{ + s = ""; + } + } + } + card->formattedTextInit = 1; + } + + + + for (unsigned int i=0; i < card->formattedText.size(); i++){ + sprintf(buf, "%s", card->formattedText[i].c_str()); + v.x = (-width/2 + 12 )*scale; + v.y = ((-height/2) + 50 + 16*i) * scale; + v.Rotate(rotation); + mFont->DrawString(buf,x+v.x,y+v.y); + } + + + + v.x = ((-width/2)+10) * scale; + v.y = ((-height/2) + 25) * scale; + v.Rotate(rotation); + int over = strlen(card->getName()) - 23; + float multiply = 1.4; + if (over > 0){ + multiply = 1.1; + } + mFont->SetScale(scale * multiply); + mFont->SetColor(ARGB(255,_r[color],_g[color],_b[color])); + mFont->DrawString(card->getName(),x+v.x,y+v.y); + mFont->SetScale(scale); + mFont->SetColor(ARGB(255,255,255,255)); + + + if (card->isACreature()){ + v.x = (width/2-40) * scale; + v.y = (height/2-30) * scale; + v.Rotate(rotation); + sprintf(buf,"%i/%i",card->power,card->toughness); + mFont->DrawString(buf,x+v.x,y+v.y); + } + +} + + +CardGui::CardGui(int id, MTGCardInstance * _card, float desiredHeight,float _x, float _y, bool hasFocus): PlayGuiObject(id, desiredHeight, _x, _y, hasFocus){ + LOG("==Creating NEW CardGui Object. CardName:"); + LOG(_card->getName()); + + card = _card; + type = GUI_CARD; + + alpha = 255; + mParticleSys = NULL; + + if (card->hasColor(MTG_COLOR_RED)){ + mParticleSys = GameApp::Particles[3]; + }else if (card->hasColor(MTG_COLOR_BLUE)){ + mParticleSys = GameApp::Particles[1]; + }else if (card->hasColor(MTG_COLOR_GREEN)){ + mParticleSys = GameApp::Particles[2]; + }else if (card->hasColor(MTG_COLOR_BLACK)){ + mParticleSys = GameApp::Particles[4]; + }else if (card->hasColor(MTG_COLOR_WHITE)){ + mParticleSys = GameApp::Particles[0]; + }else{ + mParticleSys = GameApp::Particles[5]; + } + + LOG("==CardGui Object Creation Succesfull"); +} + + +void CardGui::Update(float dt){ + alpha = 255; + + if (card->changedZoneRecently > 0) alpha = 255.f - 255.f * card->changedZoneRecently; + if (mParticleSys && card->changedZoneRecently == 1.f){ + mParticleSys->MoveTo(x+15, y+2*mHeight/3); + mParticleSys->Fire(); + } + if (card->changedZoneRecently){ + if (mParticleSys) mParticleSys->Update(dt); + card->changedZoneRecently-= (5 *dt); + if (card->changedZoneRecently < 0){ + if (mParticleSys) mParticleSys->Stop(); + } + if (card->changedZoneRecently < -3){ + card->changedZoneRecently = 0; + mParticleSys = NULL; + } + } + PlayGuiObject::Update(dt); +} + +void CardGui::RenderBig(float xpos, float ypos){ + JRenderer * renderer = JRenderer::GetInstance(); + JQuad * quad = card->getQuad(); + if (xpos == -1){ + xpos = 300; + if (x > SCREEN_WIDTH / 2) + xpos = 10; + } + 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{ + MTGCard * mtgcard = card->model; + JLBFont * font = GameApp::CommonRes->GetJLBFont("graphics/magic"); + CardGui::alternateRender(mtgcard, font, NULL, xpos + 90 , ypos + 130, 0.0f,0.9f); + } +} + +void CardGui::Render(){ + + JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); + + JRenderer * renderer = JRenderer::GetInstance(); + JQuad * quad = card->getThumb(); + if (!quad || quad->mHeight * 2 < mHeight){ + JQuad * quad2 = card->getQuad(); + if (quad2) + quad = quad2; + } + + float tap = (float)(card->isTapped()); + float rotation = M_PI_2 * tap; + if (quad){ + float mScale = mHeight / quad->mHeight; + float myX = x + (quad->mHeight/2 * tap * mScale); + float myY = y+(quad->mWidth/2 * tap * mScale); + if (mHeight-defaultHeight){ + if (card->isTapped()){ + renderer->FillRect(myX + 1*(mHeight-defaultHeight) - quad->mHeight * mScale , myY + 1*(mHeight-defaultHeight) , quad->mHeight * mScale, quad->mWidth * mScale, ARGB(128,0,0,0)); + }else{ + renderer->FillRect(myX + 1*(mHeight-defaultHeight) , myY + 1*(mHeight-defaultHeight) , quad->mWidth * mScale, quad->mHeight * mScale, ARGB(128,0,0,0)); + } + } + + quad->SetColor(ARGB( alpha,255,255,255)); + GameObserver * game = GameObserver::GetInstance(); + TargetChooser * tc = NULL; + if (game) tc = game->getCurrentTargetChooser(); + if (tc){ + if (!tc->canTarget(card)){ + quad->SetColor(ARGB( alpha,50,50,50)); + } + } + renderer->RenderQuad(quad, myX , myY , rotation,mScale,mScale); + if (tc && tc->alreadyHasTarget(card)){ + if (card->isTapped()){ + renderer->FillRect(myX- quad->mHeight * mScale , myY , quad->mHeight * mScale, quad->mWidth * mScale, ARGB(128,255,0,0)); + }else{ + renderer->FillRect(myX , myY , quad->mWidth * mScale, quad->mHeight * mScale, ARGB(128,255,0,0)); + } + } + quad->SetColor(ARGB( alpha,255,255,255)); + }else{ + int color = card->getColor(); + float mScale = mHeight / 64; + float myX = x + (32 * tap * mScale); + float myY = y+(20 * tap * mScale); + + char buffer[200]; + sprintf(buffer, "%s",card->getName()); + mFont->SetColor(ARGB(255,_r[color],_g[color],_b[color])); + if (card->isTapped()){ + renderer->FillRect(myX - 64 * mScale , myY , 64 * mScale, 40 * mScale, ARGB(255,0,0,0)); + renderer->DrawRect(myX - 64 * mScale , myY , 64 * mScale, 40 * mScale, ARGB(255,_r[color],_g[color],_b[color])); + mFont->SetScale(0.20); + mFont->DrawString(buffer,myX - (64 * mScale)+4,myY + 1); + }else{ + renderer->FillRect(myX , myY , 40 * mScale, 64 * mScale, ARGB(255,0,0,0)); + renderer->DrawRect(myX , myY , 40 * mScale, 64 * mScale, ARGB(255,_r[color],_g[color],_b[color])); + mFont->SetScale(0.40); + mFont->DrawString(buffer,myX+4,myY + 1); + } + + + mFont->SetScale(1.0); + } + if (card->isACreature()){ + mFont->SetScale(0.75); + char buffer[200]; + sprintf(buffer, "%i/%i",card->power,card->life); + renderer->FillRect(x+2,y + mHeight - 12, 25 , 12 ,ARGB(128,0,0,0)); + mFont->SetColor(ARGB(255,255,255,255)); + mFont->DrawString(buffer,x+4,y + mHeight - 10); + } + + if (mParticleSys && card->changedZoneRecently > 0){ + renderer->SetTexBlend(BLEND_SRC_ALPHA, BLEND_ONE); + mParticleSys->Render(); + // set normal blending + renderer->SetTexBlend(BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA); + } +} + + + +CardGui::~CardGui(){ + LOG("==Destroying CardGui object"); + LOG(this->card->getName()); + LOG("==CardGui object destruction Successful"); +} + + + diff --git a/projects/mtg/src/ConstraintResolver.cpp b/projects/mtg/src/ConstraintResolver.cpp index 6f2bf07d0..62d6fa4b0 100644 --- a/projects/mtg/src/ConstraintResolver.cpp +++ b/projects/mtg/src/ConstraintResolver.cpp @@ -1,41 +1,41 @@ -#include "../include/debug.h" -#include "../include/ConstraintResolver.h" - - -int ConstraintResolver::untap(GameObserver * game, MTGCardInstance * card){ - if (!card->isUntapping()){ - return 0; - } - int ok = 1; - ManaCost * untapManaCost = NEW ManaCost(); - Blockers * blockers = card->getBlockers(); - Blocker * blocker; - blockers->rewind(); - Player * player = game->currentPlayer; - while ((blocker = blockers->next())){ -#if defined (WIN32) || defined (LINUX) -char buf[4096]; -sprintf(buf, "next\n"); -OutputDebugString(buf); -#endif - untapManaCost->add(blocker->untapManaCost()); - } - if (player->getManaPool()->canAfford(untapManaCost)){ - blockers->rewind(); - while ((blocker = blockers->next())){ - if (!blocker->unblock()){ - ok = 0; - break; - } - } - }else{ - ok = 0; - } - - if (ok) { - player->getManaPool()->pay(untapManaCost); - card->untap(); - } - delete untapManaCost; - return ok; -} +#include "../include/debug.h" +#include "../include/ConstraintResolver.h" + + +int ConstraintResolver::untap(GameObserver * game, MTGCardInstance * card){ + if (!card->isUntapping()){ + return 0; + } + int ok = 1; + ManaCost * untapManaCost = NEW ManaCost(); + Blockers * blockers = card->getBlockers(); + Blocker * blocker; + blockers->rewind(); + Player * player = game->currentPlayer; + while ((blocker = blockers->next())){ +#if defined (WIN32) || defined (LINUX) + char buf[4096]; + sprintf(buf, "next\n"); + OutputDebugString(buf); +#endif + untapManaCost->add(blocker->untapManaCost()); + } + if (player->getManaPool()->canAfford(untapManaCost)){ + blockers->rewind(); + while ((blocker = blockers->next())){ + if (!blocker->unblock()){ + ok = 0; + break; + } + } + }else{ + ok = 0; + } + + if (ok) { + player->getManaPool()->pay(untapManaCost); + card->untap(); + } + delete untapManaCost; + return ok; +} diff --git a/projects/mtg/src/Counters.cpp b/projects/mtg/src/Counters.cpp index 714324447..5efd9d2ad 100644 --- a/projects/mtg/src/Counters.cpp +++ b/projects/mtg/src/Counters.cpp @@ -1,120 +1,120 @@ -#include "../include/Counters.h" -#include "../include/debug.h" -#include "../include/MTGCardInstance.h" - -Counter::Counter(MTGCardInstance * _target, int _power, int _toughness){ - init(_target,"",_power, _toughness); -} -Counter::Counter(MTGCardInstance * _target, const char * _name,int _power, int _toughness ){ - init(_target,_name,_power, _toughness); -} - - int Counter::init(MTGCardInstance * _target,const char * _name, int _power, int _toughness){ - target = _target; - name = _name; - power = _power; - toughness = _toughness; - nb = 1; - return 1; - } - - bool Counter::sameAs(const char * _name, int _power, int _toughness){ - if (power == 0 && toughness == 0) return (name.compare(_name) == 0); - return (power == _power && toughness == _toughness); - } - - bool Counter::cancels(int _power, int _toughness){ - if (power == 0 && toughness == 0) return false; - return (power == -_power && toughness == -_toughness); - } - - int Counter::added(){ - if (power != 0 || toughness != 0){ - target->power+= power; - target->addToToughness(toughness); - } - return 1; - } - - int Counter::removed(){ - if (power != 0 || toughness != 0){ - target->power-= power; - target->addToToughness(-toughness); - } - return 1; - } - - - Counters::Counters(MTGCardInstance * _target):target(_target){ - mCount = 0; - } - Counters::~Counters(){ - for (int i = 0; i < mCount; i++){ - delete counters[i]; - } - } - - int Counters::addCounter(const char * _name,int _power, int _toughness){ - for (int i = 0; i < mCount; i++){ - if (counters[i]->cancels( _power,_toughness) && counters[i]->nb > 0){ - counters[i]->removed(); - counters[i]->nb--; - return mCount; - } - } - - for (int i = 0; i < mCount; i++){ - if (counters[i]->sameAs(_name, _power,_toughness)){ - counters[i]->added(); - counters[i]->nb++; - return mCount; - } - } - Counter * counter = NEW Counter(target,_name, _power, _toughness); - counters[mCount] = counter; - counter->added(); - mCount++; - return mCount; - } - - int Counters::addCounter(int _power, int _toughness){ - return addCounter("",_power, _toughness); - } - - int Counters::removeCounter(const char * _name,int _power, int _toughness){ - for (int i = 0; i < mCount; i++){ - if (counters[i]->sameAs(_name, _power,_toughness)){ - if (counters[i]->nb < 1) return 0; - counters[i]->removed(); - counters[i]->nb--; - return mCount; - } - } - return 0; - } - - int Counters::removeCounter(int _power, int _toughness){ - return removeCounter("",_power, _toughness); - } - - Counter * Counters::hasCounter(const char * _name,int _power, int _toughness){ - for (int i = 0; i < mCount; i++){ - if (counters[i]->sameAs(_name, _power,_toughness)){ - if (counters[i]->nb > 0) return counters[i]; - } - } - return NULL; - } - - Counter * Counters::hasCounter(int _power , int _toughness ){ - return hasCounter("",_power, _toughness); - } - - Counter * Counters::getNext(Counter * previous){ - int found = 0; - for (int i = 0; i < mCount ; i++){ - if (found && counters[i]->nb > 0) return counters[i]; - if (counters[i] == previous) found = 1; - } - return NULL; - } +#include "../include/Counters.h" +#include "../include/debug.h" +#include "../include/MTGCardInstance.h" + +Counter::Counter(MTGCardInstance * _target, int _power, int _toughness){ + init(_target,"",_power, _toughness); +} +Counter::Counter(MTGCardInstance * _target, const char * _name,int _power, int _toughness ){ + init(_target,_name,_power, _toughness); +} + +int Counter::init(MTGCardInstance * _target,const char * _name, int _power, int _toughness){ + target = _target; + name = _name; + power = _power; + toughness = _toughness; + nb = 1; + return 1; +} + +bool Counter::sameAs(const char * _name, int _power, int _toughness){ + if (power == 0 && toughness == 0) return (name.compare(_name) == 0); + return (power == _power && toughness == _toughness); +} + +bool Counter::cancels(int _power, int _toughness){ + if (power == 0 && toughness == 0) return false; + return (power == -_power && toughness == -_toughness); +} + +int Counter::added(){ + if (power != 0 || toughness != 0){ + target->power+= power; + target->addToToughness(toughness); + } + return 1; +} + +int Counter::removed(){ + if (power != 0 || toughness != 0){ + target->power-= power; + target->addToToughness(-toughness); + } + return 1; +} + + +Counters::Counters(MTGCardInstance * _target):target(_target){ + mCount = 0; +} +Counters::~Counters(){ + for (int i = 0; i < mCount; i++){ + delete counters[i]; + } +} + +int Counters::addCounter(const char * _name,int _power, int _toughness){ + for (int i = 0; i < mCount; i++){ + if (counters[i]->cancels( _power,_toughness) && counters[i]->nb > 0){ + counters[i]->removed(); + counters[i]->nb--; + return mCount; + } + } + + for (int i = 0; i < mCount; i++){ + if (counters[i]->sameAs(_name, _power,_toughness)){ + counters[i]->added(); + counters[i]->nb++; + return mCount; + } + } + Counter * counter = NEW Counter(target,_name, _power, _toughness); + counters[mCount] = counter; + counter->added(); + mCount++; + return mCount; +} + +int Counters::addCounter(int _power, int _toughness){ + return addCounter("",_power, _toughness); +} + +int Counters::removeCounter(const char * _name,int _power, int _toughness){ + for (int i = 0; i < mCount; i++){ + if (counters[i]->sameAs(_name, _power,_toughness)){ + if (counters[i]->nb < 1) return 0; + counters[i]->removed(); + counters[i]->nb--; + return mCount; + } + } + return 0; +} + +int Counters::removeCounter(int _power, int _toughness){ + return removeCounter("",_power, _toughness); +} + +Counter * Counters::hasCounter(const char * _name,int _power, int _toughness){ + for (int i = 0; i < mCount; i++){ + if (counters[i]->sameAs(_name, _power,_toughness)){ + if (counters[i]->nb > 0) return counters[i]; + } + } + return NULL; +} + +Counter * Counters::hasCounter(int _power , int _toughness ){ + return hasCounter("",_power, _toughness); +} + +Counter * Counters::getNext(Counter * previous){ + int found = 0; + for (int i = 0; i < mCount ; i++){ + if (found && counters[i]->nb > 0) return counters[i]; + if (counters[i] == previous) found = 1; + } + return NULL; +} diff --git a/projects/mtg/src/Damage.cpp b/projects/mtg/src/Damage.cpp index 1b43833fd..db70e959d 100644 --- a/projects/mtg/src/Damage.cpp +++ b/projects/mtg/src/Damage.cpp @@ -1,142 +1,142 @@ -#include "../include/debug.h" -#include "../include/Damage.h" -#include "../include/MTGCardInstance.h" -#include "../include/Counters.h" - -Damage::Damage(int id, MTGCardInstance * _source, Damageable * _target): Interruptible(id){ - init(_source, _target, _source->getPower()); -} - -Damage::Damage(int id, MTGCardInstance * _source, Damageable * _target, int _damage): Interruptible(id){ - init(_source, _target, _damage); -} - -void Damage::init(MTGCardInstance * _source, Damageable * _target, int _damage){ - target = _target; - source = _source; - - - if (_damage < 0) _damage = 0; //Negative damages cannot happen - damage = _damage; - mHeight = 40; - type = ACTION_DAMAGE; -} - -int Damage::resolve(){ - if (damage <0) damage = 0; //Negative damages cannot happen - if (target->type_as_damageable == DAMAGEABLE_MTGCARDINSTANCE){ - MTGCardInstance * _target = (MTGCardInstance *)target; - if ((_target)->protectedAgainst(source)) return 0; - // Damage for WITHER on creatures - if (source->has(WITHER)){ - for (int i = 0; i < damage; i++){ - _target->counters->addCounter(-1, -1); - } - return 1; - } - _target->doDamageTest = 1; - } - - int a = target->dealDamage(damage); - return a; -} - -void Damage::Render(){ - JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); - mFont->SetBase(0); - mFont->SetScale(0.75); - char buffer[200]; - sprintf(buffer, "Does %i damage to", damage); - mFont->DrawString(buffer, x + 20 , y, JGETEXT_LEFT); - JRenderer * renderer = JRenderer::GetInstance(); - JQuad * quad = source->getThumb(); - if (quad){ - float scale = 30 / quad->mHeight; - renderer->RenderQuad(quad, x , y , 0,scale,scale); - }else{ - //TODO - } - quad = target->getIcon(); - if (quad){ - float scale = 30 / quad->mHeight; - renderer->RenderQuad(quad, x + 150 , y , 0,scale,scale); - }else{ - //TODO - } - -} - -DamageStack::DamageStack(int id, GameObserver * _game):GuiLayer(id, _game), Interruptible(id){ - currentState = -1; - type = ACTION_DAMAGES; -} - -int DamageStack::CombatDamages(){ - CombatDamages(1); - CombatDamages(0); - return 1; -} - -int DamageStack::CombatDamages(int strike){ - mHeight = 0; - MTGInPlay * attackers = game->currentPlayer->game->inPlay; - MTGInPlay * defensers = game->opponent()->game->inPlay; - - MTGCardInstance * attacker = attackers->getNextAttacker(NULL); - while (attacker != NULL){ - int nbdefensers = defensers->nbDefensers(attacker); - if ((!strike && !attacker->has(FIRSTSTRIKE)) || (strike && attacker->has(FIRSTSTRIKE)) || attacker->has(DOUBLESTRIKE)){ - if (nbdefensers == 0){ - Damage * damage = NEW Damage (mCount, attacker, game->opponent()); - Add(damage); - }else if (nbdefensers == 1){ - Damage * damage = NEW Damage (mCount, attacker, defensers->getNextDefenser(NULL, attacker)); - Add(damage); - }else{ - //TODO Fetch list of defensers and allow user to choose targets - Damage * damage = NEW Damage (mCount, attacker, defensers->getNextDefenser(NULL, attacker)); - Add(damage); - } - } - MTGCardInstance * defenser = defensers->getNextDefenser(NULL, attacker); - while (defenser != NULL){ - if ((!strike && !defenser->has(FIRSTSTRIKE)) || (strike && defenser->has(FIRSTSTRIKE)) || defenser->has(DOUBLESTRIKE)){ - Damage * damage = NEW Damage (mCount,defenser, attacker); - Add(damage); - } - defenser = defensers->getNextDefenser(defenser, attacker); - } - attacker = attackers->getNextAttacker(attacker); - } - - for (int i = 0; i < mCount; i++){ - Damage * damage = (Damage*)mObjects[i]; - mHeight += damage->mHeight; - } - - return mCount; -} - -int DamageStack::resolve(){ - for (int i = mCount-1; i>= 0; i--){ - Damage * damage = (Damage*)mObjects[i]; - damage->resolve(); - } - for (int i = mCount-1; i>= 0; i--){ - Damage * damage = (Damage*)mObjects[i]; - damage->target->afterDamage(); - } - return 1; -} - -void DamageStack::Render(){ - int currenty = y; - for (int i= 0; i < mCount; i++){ - Damage * damage = (Damage*)mObjects[i]; - damage->x = x; - damage->y = currenty; - currenty += damage->mHeight; - damage->Render(); - } -} +#include "../include/debug.h" +#include "../include/Damage.h" +#include "../include/MTGCardInstance.h" +#include "../include/Counters.h" + +Damage::Damage(int id, MTGCardInstance * _source, Damageable * _target): Interruptible(id){ + init(_source, _target, _source->getPower()); +} + +Damage::Damage(int id, MTGCardInstance * _source, Damageable * _target, int _damage): Interruptible(id){ + init(_source, _target, _damage); +} + +void Damage::init(MTGCardInstance * _source, Damageable * _target, int _damage){ + target = _target; + source = _source; + + + if (_damage < 0) _damage = 0; //Negative damages cannot happen + damage = _damage; + mHeight = 40; + type = ACTION_DAMAGE; +} + +int Damage::resolve(){ + if (damage <0) damage = 0; //Negative damages cannot happen + if (target->type_as_damageable == DAMAGEABLE_MTGCARDINSTANCE){ + MTGCardInstance * _target = (MTGCardInstance *)target; + if ((_target)->protectedAgainst(source)) return 0; + // Damage for WITHER on creatures + if (source->has(WITHER)){ + for (int i = 0; i < damage; i++){ + _target->counters->addCounter(-1, -1); + } + return 1; + } + _target->doDamageTest = 1; + } + + int a = target->dealDamage(damage); + return a; +} + +void Damage::Render(){ + JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); + mFont->SetBase(0); + mFont->SetScale(0.75); + char buffer[200]; + sprintf(buffer, "Does %i damage to", damage); + mFont->DrawString(buffer, x + 20 , y, JGETEXT_LEFT); + JRenderer * renderer = JRenderer::GetInstance(); + JQuad * quad = source->getThumb(); + if (quad){ + float scale = 30 / quad->mHeight; + renderer->RenderQuad(quad, x , y , 0,scale,scale); + }else{ + //TODO + } + quad = target->getIcon(); + if (quad){ + float scale = 30 / quad->mHeight; + renderer->RenderQuad(quad, x + 150 , y , 0,scale,scale); + }else{ + //TODO + } + +} + +DamageStack::DamageStack(int id, GameObserver * _game):GuiLayer(id, _game), Interruptible(id){ + currentState = -1; + type = ACTION_DAMAGES; +} + +int DamageStack::CombatDamages(){ + CombatDamages(1); + CombatDamages(0); + return 1; +} + +int DamageStack::CombatDamages(int strike){ + mHeight = 0; + MTGInPlay * attackers = game->currentPlayer->game->inPlay; + MTGInPlay * defensers = game->opponent()->game->inPlay; + + MTGCardInstance * attacker = attackers->getNextAttacker(NULL); + while (attacker != NULL){ + int nbdefensers = defensers->nbDefensers(attacker); + if ((!strike && !attacker->has(FIRSTSTRIKE)) || (strike && attacker->has(FIRSTSTRIKE)) || attacker->has(DOUBLESTRIKE)){ + if (nbdefensers == 0){ + Damage * damage = NEW Damage (mCount, attacker, game->opponent()); + Add(damage); + }else if (nbdefensers == 1){ + Damage * damage = NEW Damage (mCount, attacker, defensers->getNextDefenser(NULL, attacker)); + Add(damage); + }else{ + //TODO Fetch list of defensers and allow user to choose targets + Damage * damage = NEW Damage (mCount, attacker, defensers->getNextDefenser(NULL, attacker)); + Add(damage); + } + } + MTGCardInstance * defenser = defensers->getNextDefenser(NULL, attacker); + while (defenser != NULL){ + if ((!strike && !defenser->has(FIRSTSTRIKE)) || (strike && defenser->has(FIRSTSTRIKE)) || defenser->has(DOUBLESTRIKE)){ + Damage * damage = NEW Damage (mCount,defenser, attacker); + Add(damage); + } + defenser = defensers->getNextDefenser(defenser, attacker); + } + attacker = attackers->getNextAttacker(attacker); + } + + for (int i = 0; i < mCount; i++){ + Damage * damage = (Damage*)mObjects[i]; + mHeight += damage->mHeight; + } + + return mCount; +} + +int DamageStack::resolve(){ + for (int i = mCount-1; i>= 0; i--){ + Damage * damage = (Damage*)mObjects[i]; + damage->resolve(); + } + for (int i = mCount-1; i>= 0; i--){ + Damage * damage = (Damage*)mObjects[i]; + damage->target->afterDamage(); + } + return 1; +} + +void DamageStack::Render(){ + int currenty = y; + for (int i= 0; i < mCount; i++){ + Damage * damage = (Damage*)mObjects[i]; + damage->x = x; + damage->y = currenty; + currenty += damage->mHeight; + damage->Render(); + } +} diff --git a/projects/mtg/src/DamageResolverLayer.cpp b/projects/mtg/src/DamageResolverLayer.cpp index 21cb2a6f2..ca031bede 100644 --- a/projects/mtg/src/DamageResolverLayer.cpp +++ b/projects/mtg/src/DamageResolverLayer.cpp @@ -1,359 +1,359 @@ -#include "../include/debug.h" -#include "../include/DamageResolverLayer.h" -#include "../include/GameObserver.h" -#include "../include/MTGCardInstance.h" -#include "../include/DamagerDamaged.h" -#include "../include/Damage.h" - -DamageResolverLayer::DamageResolverLayer(int id, GameObserver * _game):PlayGuiObjectController(id, _game){ - currentPhase = -1; - remainingDamageSteps = 0; - damageStack = NULL; - currentSource = NULL; - buttonOk = 0; - currentChoosingPlayer = NULL; -} -void DamageResolverLayer::Update(float dt){ - int newPhase = game->getCurrentGamePhase(); - if (newPhase == MTG_PHASE_COMBATDAMAGE){ - if (!game->mLayers->stackLayer()->getNext(NULL,0,NOT_RESOLVED)){ - - if (newPhase != currentPhase){ - init(); - } - if (remainingDamageSteps && empty()){ - initResolve(); - } - } - }else{ - remainingDamageSteps = 0; - } - currentPhase = newPhase; - PlayGuiObjectController::Update(dt); -} - - -Player * DamageResolverLayer::whoSelectsDamagesDealtBy(MTGCardInstance * card){ - if (card->controller() == game->currentPlayer){ //Attacker - MTGInPlay * defensers = game->opponent()->game->inPlay; - int nbdefensers = defensers->nbDefensers(card); - if (nbdefensers == 0) return NULL; - if(nbdefensers == 1 && !card->has(TRAMPLE)) return NULL; - MTGCardInstance * defenser = defensers->getNextDefenser(NULL, card); - while (defenser != NULL){ - if (defenser->has(BANDING)) return game->opponent(); - defenser = defensers->getNextDefenser(defenser, card); - } - return game->currentPlayer; - }else{ //Defenser - MTGInPlay * attackers = game->currentPlayer->game->inPlay; - int nbattackers = attackers->nbPartners(card->isDefenser()); - if(nbattackers <= 1) return NULL; - if (card->isDefenser()->banding) return game->currentPlayer; - return game->opponent(); - } -} - -int DamageResolverLayer::addAutoDamageToOpponents(MTGCardInstance * card){ - if (card->controller() == game->currentPlayer){ //Attacker - MTGInPlay * defensers = game->opponent()->game->inPlay; - int nbdefensers = defensers->nbDefensers(card); - if (nbdefensers == 0){ - Damage * damage = NEW Damage (0, card, game->opponent()); - damageStack->Add(damage); - }else if (nbdefensers == 1){ - Damage * damage = NEW Damage (0, card, defensers->getNextDefenser(NULL, card)); - damageStack->Add(damage); - }else{ - //SHOULDN'T HAPPEN ! - } - }else{ //Defenser - Damage * damage = NEW Damage (mCount,card, card->isDefenser()); - damageStack->Add(damage); - } - return 1; -} - - -int DamageResolverLayer::addIfNotExists(MTGCardInstance * card, Player * selecter){ - for (int i = 0; i < mCount; i++){ - DamagerDamaged * item = (DamagerDamaged *)mObjects[i]; - if (item->card == card) return 0; - } - CardGui * cardg = game->mLayers->playLayer()->getByCard(card); - DamagerDamaged * item = NEW DamagerDamaged(cardg, selecter, mCount == 0); - Add(item); - mCurr = 0; - return 1; -} - - -//Adds a card and all its opponents to the Damagers' list -int DamageResolverLayer::addDamager(MTGCardInstance * card, Player * selecter){ - addIfNotExists(card, selecter); - if (card->controller() == game->currentPlayer){ //Attacker - MTGInPlay * defensers = game->opponent()->game->inPlay; - MTGCardInstance * defenser = defensers->getNextDefenser(NULL, card); - while (defenser != NULL){ - addIfNotExists(defenser, whoSelectsDamagesDealtBy(defenser)); - defenser = defensers->getNextDefenser(defenser, card); - } - }else{ //Defenser - MTGInPlay * attackers = game->currentPlayer->game->inPlay; - MTGCardInstance * attacker = card->isDefenser(); - addIfNotExists(attacker,whoSelectsDamagesDealtBy(attacker)); - MTGCardInstance * banding = attacker->banding; - if (banding){ - attacker = attackers->getNextAttacker(NULL); - while (attacker != NULL){ - if (attacker->banding == banding){ - addIfNotExists(attacker,whoSelectsDamagesDealtBy(attacker)); - } - attacker = attackers->getNextAttacker(attacker); - } - } - } - return 1; -} - -int DamageResolverLayer::initResolve(){ -#if defined (WIN32) || defined (LINUX) - char buf[4096]; - sprintf(buf, "starting resolve, remainingDamagesStep = %i\n", remainingDamageSteps); - OutputDebugString(buf); -#endif - if (damageStack) return 0; - -#if defined (WIN32) || defined (LINUX) - sprintf(buf, "damageStack is NULL, we can resolve \n"); - OutputDebugString(buf); -#endif - currentSource = NULL; - currentChoosingPlayer = game->currentPlayer; - damageStack = NEW DamageStack(mCount,game); - int strike = 0; - if (remainingDamageSteps == 2) strike = 1; - - MTGInPlay * attackers = game->currentPlayer->game->inPlay; - MTGInPlay * defensers = game->opponent()->game->inPlay; - - MTGCardInstance * attacker = attackers->getNextAttacker(NULL); - while (attacker != NULL){ -#if defined (WIN32) || defined (LINUX) - sprintf(buf, "attacker : %s \n", attacker->getName()); - OutputDebugString(buf); -#endif - if ((!strike && !attacker->has(FIRSTSTRIKE)) || (strike && attacker->has(FIRSTSTRIKE)) || attacker->has(DOUBLESTRIKE)){ - Player * selecter = whoSelectsDamagesDealtBy(attacker); - if (!selecter){ - addAutoDamageToOpponents(attacker); - }else{ - addDamager(attacker, selecter); - } - } - MTGCardInstance * defenser = defensers->getNextDefenser(NULL, attacker); - while (defenser != NULL){ - if ((!strike && !defenser->has(FIRSTSTRIKE)) || (strike && defenser->has(FIRSTSTRIKE)) || defenser->has(DOUBLESTRIKE)){ - Player * selecterb = whoSelectsDamagesDealtBy(defenser); - if (!selecterb){ - addAutoDamageToOpponents(defenser); - }else{ - addDamager(defenser, selecterb); - } - } - defenser = defensers->getNextDefenser(defenser, attacker); - } - attacker = attackers->getNextAttacker(attacker); - } - - if (empty()){ - if (!damageStack->empty()){ - game->mLayers->stackLayer()->addAction(damageStack); - }else{ - SAFE_DELETE(damageStack); - } - remainingDamageSteps--; - damageStack = NULL; - modal = remainingDamageSteps; - }else{ - if (canStopDealDamages()) currentChoosingPlayer = game->opponent(); - } - return 1; -} -int DamageResolverLayer::init(){ - modal = 1; - remainingDamageSteps = 2; - return 1; -} - -DamagerDamaged * DamageResolverLayer::findByCard(MTGCardInstance * card){ - for (int i =0; i < mCount; i++){ - DamagerDamaged * current = (DamagerDamaged *) mObjects[i]; - if (current->card == card) return current; - } - return NULL; -} - -//Returns 1 if all "compulsory" damages have been assigned for current player -int DamageResolverLayer::canStopDealDamages(){ - for (int i = 0; i < mCount ; i ++){ - DamagerDamaged * current = (DamagerDamaged *) mObjects[i]; - if (current->damageSelecter==currentChoosingPlayer && current->damageToDeal > 0){ - MTGCardInstance * card = current->card; - if (card->controller() == game->currentPlayer){ //Attacker - if (card->has(TRAMPLE)){ - MTGInPlay * defensers = game->opponent()->game->inPlay; - MTGCardInstance * defenser = defensers->getNextDefenser(NULL, card); - while (defenser != NULL){ - DamagerDamaged * _defenser = findByCard(defenser); - if (!_defenser->hasLethalDamage()) return 0; - defenser = defensers->getNextDefenser(defenser, card); - } - }else{ - return 0; - } - }else{ //Defenser - return 0; - } - } - } - return 1; -} - -int DamageResolverLayer::trampleDamage(){ - for (int i = 0; i < mCount ; i ++){ - DamagerDamaged * current = (DamagerDamaged *) mObjects[i]; - if (current->damageToDeal > 0){ - MTGCardInstance * card = current->card; - if (card->controller() == game->currentPlayer){ //Attacker - if (card->has(TRAMPLE)){ - Damage * damage = NEW Damage(0, card, game->opponent(), current->damageToDeal); - damageStack->Add(damage); - } - } - } - } - return 1; -} - -int DamageResolverLayer::resolveDamages(){ - trampleDamage(); - for (int i = 0; i < mCount ; i++){ - DamagerDamaged * current = (DamagerDamaged *) mObjects[i]; - for (int j =0; j < current->mCount ; j++){ - Damage * damage = NEW Damage(0, current->damages[j]->source, current->damages[j]->target, current->damages[j]->damage); - damageStack->Add(damage); - } - } - game->mLayers->stackLayer()->addAction(damageStack); - remainingDamageSteps--; - resetObjects(); - damageStack = NULL; - modal = remainingDamageSteps; - return 1; -} - -//a and b are opponents if b is blocking a band in which a belongs or blocking directly a -int DamageResolverLayer::isOpponent(DamagerDamaged * a, DamagerDamaged * b){ - MTGCardInstance * carda = a->card; - MTGCardInstance * cardb = b->card; - if (cardb->controller() == game->currentPlayer) {//if b is the attacker switch the cards - carda = cardb; - cardb = a->card; - } - if (cardb->controller() == game->currentPlayer || carda->controller() == game->opponent()) return 0; //Same team, idiot ! - - if (!carda->banding){ - if (cardb->isDefenser() == carda) return 1; - return 0; - } - - if (cardb->isDefenser() && cardb->isDefenser()->banding == carda->banding) return 1; - return 0; -} - -void DamageResolverLayer::nextPlayer(){ - if (currentChoosingPlayer == game->currentPlayer){ - currentChoosingPlayer = game->opponent(); - if (canStopDealDamages()) resolveDamages(); - }else{ - resolveDamages(); - } - -} -void DamageResolverLayer::CheckUserInput(float dt){ - if (!mCount) return; - if (mEngine->GetButtonClick(PSP_CTRL_CIRCLE)){ - if (mObjects[mCurr] && mObjects[mCurr]->ButtonPressed()){ - DamagerDamaged * current = (DamagerDamaged *) mObjects[mCurr]; - if (!currentSource || !isOpponent(current,currentSource)){ - for (int i = 0; i < mCount; i++){ - DamagerDamaged * _current = (DamagerDamaged *) mObjects[i]; - if (isOpponent(current,_current)){ - currentSource = _current; - break; - } - } - } - if (currentSource){ - if (currentSource->damageSelecter == currentChoosingPlayer){ - if (isOpponent(current,currentSource)){ - if (!currentSource->dealOneDamage(current)){ - currentSource->removeDamagesTo(current); - } - } - } - }else{ - if (current->damageSelecter == currentChoosingPlayer){ - currentSource = current; - } - } - buttonOk = 0; - if (canStopDealDamages()) buttonOk = 1; - } - }else if (mEngine->GetButtonClick(PSP_CTRL_CROSS)){ - if (mObjects[mCurr] && mObjects[mCurr]->ButtonPressed()){ - DamagerDamaged * current = (DamagerDamaged *) mObjects[mCurr]; - if (current->damageSelecter == currentChoosingPlayer){ - currentSource = current; - } - } - }else if (mEngine->GetButtonClick(PSP_CTRL_SQUARE)){ - if (canStopDealDamages()){ - nextPlayer(); - //switch to next player or end of selection - } - }else{ - PlayGuiObjectController::CheckUserInput(dt); - } -} - -void DamageResolverLayer::Render(){ - if (!mCount) return; - JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); - mFont->SetBase(0); - mFont->SetScale(0.75); - - JRenderer * renderer = JRenderer::GetInstance(); - renderer->FillRect(0 ,0 , SCREEN_WIDTH , SCREEN_HEIGHT , ARGB(200,0,0,0)); - if (currentChoosingPlayer == game->currentPlayer){ - mFont->DrawString("Player 1", 0,0); - }else{ - mFont->DrawString("Player 2", 0,0); - } - if (currentSource){ - currentSource->RenderBig(10, 20); - mFont->DrawString("Current Damager:", 10, 5); - } - for (int i = 0; i < mCount; i++){ - ((DamagerDamaged *)mObjects[i])->Render(currentChoosingPlayer); - } - if (mObjects[mCurr]){ - ((DamagerDamaged *)mObjects[mCurr])->Render(currentChoosingPlayer); - } - - - if (buttonOk){ - mFont->DrawString("Damages Assigned, Click Square to Continue", 250, 5); - } -} +#include "../include/debug.h" +#include "../include/DamageResolverLayer.h" +#include "../include/GameObserver.h" +#include "../include/MTGCardInstance.h" +#include "../include/DamagerDamaged.h" +#include "../include/Damage.h" + +DamageResolverLayer::DamageResolverLayer(int id, GameObserver * _game):PlayGuiObjectController(id, _game){ + currentPhase = -1; + remainingDamageSteps = 0; + damageStack = NULL; + currentSource = NULL; + buttonOk = 0; + currentChoosingPlayer = NULL; +} +void DamageResolverLayer::Update(float dt){ + int newPhase = game->getCurrentGamePhase(); + if (newPhase == MTG_PHASE_COMBATDAMAGE){ + if (!game->mLayers->stackLayer()->getNext(NULL,0,NOT_RESOLVED)){ + + if (newPhase != currentPhase){ + init(); + } + if (remainingDamageSteps && empty()){ + initResolve(); + } + } + }else{ + remainingDamageSteps = 0; + } + currentPhase = newPhase; + PlayGuiObjectController::Update(dt); +} + + +Player * DamageResolverLayer::whoSelectsDamagesDealtBy(MTGCardInstance * card){ + if (card->controller() == game->currentPlayer){ //Attacker + MTGInPlay * defensers = game->opponent()->game->inPlay; + int nbdefensers = defensers->nbDefensers(card); + if (nbdefensers == 0) return NULL; + if(nbdefensers == 1 && !card->has(TRAMPLE)) return NULL; + MTGCardInstance * defenser = defensers->getNextDefenser(NULL, card); + while (defenser != NULL){ + if (defenser->has(BANDING)) return game->opponent(); + defenser = defensers->getNextDefenser(defenser, card); + } + return game->currentPlayer; + }else{ //Defenser + MTGInPlay * attackers = game->currentPlayer->game->inPlay; + int nbattackers = attackers->nbPartners(card->isDefenser()); + if(nbattackers <= 1) return NULL; + if (card->isDefenser()->banding) return game->currentPlayer; + return game->opponent(); + } +} + +int DamageResolverLayer::addAutoDamageToOpponents(MTGCardInstance * card){ + if (card->controller() == game->currentPlayer){ //Attacker + MTGInPlay * defensers = game->opponent()->game->inPlay; + int nbdefensers = defensers->nbDefensers(card); + if (nbdefensers == 0){ + Damage * damage = NEW Damage (0, card, game->opponent()); + damageStack->Add(damage); + }else if (nbdefensers == 1){ + Damage * damage = NEW Damage (0, card, defensers->getNextDefenser(NULL, card)); + damageStack->Add(damage); + }else{ + //SHOULDN'T HAPPEN ! + } + }else{ //Defenser + Damage * damage = NEW Damage (mCount,card, card->isDefenser()); + damageStack->Add(damage); + } + return 1; +} + + +int DamageResolverLayer::addIfNotExists(MTGCardInstance * card, Player * selecter){ + for (int i = 0; i < mCount; i++){ + DamagerDamaged * item = (DamagerDamaged *)mObjects[i]; + if (item->card == card) return 0; + } + CardGui * cardg = game->mLayers->playLayer()->getByCard(card); + DamagerDamaged * item = NEW DamagerDamaged(cardg, selecter, mCount == 0); + Add(item); + mCurr = 0; + return 1; +} + + +//Adds a card and all its opponents to the Damagers' list +int DamageResolverLayer::addDamager(MTGCardInstance * card, Player * selecter){ + addIfNotExists(card, selecter); + if (card->controller() == game->currentPlayer){ //Attacker + MTGInPlay * defensers = game->opponent()->game->inPlay; + MTGCardInstance * defenser = defensers->getNextDefenser(NULL, card); + while (defenser != NULL){ + addIfNotExists(defenser, whoSelectsDamagesDealtBy(defenser)); + defenser = defensers->getNextDefenser(defenser, card); + } + }else{ //Defenser + MTGInPlay * attackers = game->currentPlayer->game->inPlay; + MTGCardInstance * attacker = card->isDefenser(); + addIfNotExists(attacker,whoSelectsDamagesDealtBy(attacker)); + MTGCardInstance * banding = attacker->banding; + if (banding){ + attacker = attackers->getNextAttacker(NULL); + while (attacker != NULL){ + if (attacker->banding == banding){ + addIfNotExists(attacker,whoSelectsDamagesDealtBy(attacker)); + } + attacker = attackers->getNextAttacker(attacker); + } + } + } + return 1; +} + +int DamageResolverLayer::initResolve(){ +#if defined (WIN32) || defined (LINUX) + char buf[4096]; + sprintf(buf, "starting resolve, remainingDamagesStep = %i\n", remainingDamageSteps); + OutputDebugString(buf); +#endif + if (damageStack) return 0; + +#if defined (WIN32) || defined (LINUX) + sprintf(buf, "damageStack is NULL, we can resolve \n"); + OutputDebugString(buf); +#endif + currentSource = NULL; + currentChoosingPlayer = game->currentPlayer; + damageStack = NEW DamageStack(mCount,game); + int strike = 0; + if (remainingDamageSteps == 2) strike = 1; + + MTGInPlay * attackers = game->currentPlayer->game->inPlay; + MTGInPlay * defensers = game->opponent()->game->inPlay; + + MTGCardInstance * attacker = attackers->getNextAttacker(NULL); + while (attacker != NULL){ +#if defined (WIN32) || defined (LINUX) + sprintf(buf, "attacker : %s \n", attacker->getName()); + OutputDebugString(buf); +#endif + if ((!strike && !attacker->has(FIRSTSTRIKE)) || (strike && attacker->has(FIRSTSTRIKE)) || attacker->has(DOUBLESTRIKE)){ + Player * selecter = whoSelectsDamagesDealtBy(attacker); + if (!selecter){ + addAutoDamageToOpponents(attacker); + }else{ + addDamager(attacker, selecter); + } + } + MTGCardInstance * defenser = defensers->getNextDefenser(NULL, attacker); + while (defenser != NULL){ + if ((!strike && !defenser->has(FIRSTSTRIKE)) || (strike && defenser->has(FIRSTSTRIKE)) || defenser->has(DOUBLESTRIKE)){ + Player * selecterb = whoSelectsDamagesDealtBy(defenser); + if (!selecterb){ + addAutoDamageToOpponents(defenser); + }else{ + addDamager(defenser, selecterb); + } + } + defenser = defensers->getNextDefenser(defenser, attacker); + } + attacker = attackers->getNextAttacker(attacker); + } + + if (empty()){ + if (!damageStack->empty()){ + game->mLayers->stackLayer()->addAction(damageStack); + }else{ + SAFE_DELETE(damageStack); + } + remainingDamageSteps--; + damageStack = NULL; + modal = remainingDamageSteps; + }else{ + if (canStopDealDamages()) currentChoosingPlayer = game->opponent(); + } + return 1; +} +int DamageResolverLayer::init(){ + modal = 1; + remainingDamageSteps = 2; + return 1; +} + +DamagerDamaged * DamageResolverLayer::findByCard(MTGCardInstance * card){ + for (int i =0; i < mCount; i++){ + DamagerDamaged * current = (DamagerDamaged *) mObjects[i]; + if (current->card == card) return current; + } + return NULL; +} + +//Returns 1 if all "compulsory" damages have been assigned for current player +int DamageResolverLayer::canStopDealDamages(){ + for (int i = 0; i < mCount ; i ++){ + DamagerDamaged * current = (DamagerDamaged *) mObjects[i]; + if (current->damageSelecter==currentChoosingPlayer && current->damageToDeal > 0){ + MTGCardInstance * card = current->card; + if (card->controller() == game->currentPlayer){ //Attacker + if (card->has(TRAMPLE)){ + MTGInPlay * defensers = game->opponent()->game->inPlay; + MTGCardInstance * defenser = defensers->getNextDefenser(NULL, card); + while (defenser != NULL){ + DamagerDamaged * _defenser = findByCard(defenser); + if (!_defenser->hasLethalDamage()) return 0; + defenser = defensers->getNextDefenser(defenser, card); + } + }else{ + return 0; + } + }else{ //Defenser + return 0; + } + } + } + return 1; +} + +int DamageResolverLayer::trampleDamage(){ + for (int i = 0; i < mCount ; i ++){ + DamagerDamaged * current = (DamagerDamaged *) mObjects[i]; + if (current->damageToDeal > 0){ + MTGCardInstance * card = current->card; + if (card->controller() == game->currentPlayer){ //Attacker + if (card->has(TRAMPLE)){ + Damage * damage = NEW Damage(0, card, game->opponent(), current->damageToDeal); + damageStack->Add(damage); + } + } + } + } + return 1; +} + +int DamageResolverLayer::resolveDamages(){ + trampleDamage(); + for (int i = 0; i < mCount ; i++){ + DamagerDamaged * current = (DamagerDamaged *) mObjects[i]; + for (int j =0; j < current->mCount ; j++){ + Damage * damage = NEW Damage(0, current->damages[j]->source, current->damages[j]->target, current->damages[j]->damage); + damageStack->Add(damage); + } + } + game->mLayers->stackLayer()->addAction(damageStack); + remainingDamageSteps--; + resetObjects(); + damageStack = NULL; + modal = remainingDamageSteps; + return 1; +} + +//a and b are opponents if b is blocking a band in which a belongs or blocking directly a +int DamageResolverLayer::isOpponent(DamagerDamaged * a, DamagerDamaged * b){ + MTGCardInstance * carda = a->card; + MTGCardInstance * cardb = b->card; + if (cardb->controller() == game->currentPlayer) {//if b is the attacker switch the cards + carda = cardb; + cardb = a->card; + } + if (cardb->controller() == game->currentPlayer || carda->controller() == game->opponent()) return 0; //Same team, idiot ! + + if (!carda->banding){ + if (cardb->isDefenser() == carda) return 1; + return 0; + } + + if (cardb->isDefenser() && cardb->isDefenser()->banding == carda->banding) return 1; + return 0; +} + +void DamageResolverLayer::nextPlayer(){ + if (currentChoosingPlayer == game->currentPlayer){ + currentChoosingPlayer = game->opponent(); + if (canStopDealDamages()) resolveDamages(); + }else{ + resolveDamages(); + } + +} +void DamageResolverLayer::CheckUserInput(float dt){ + if (!mCount) return; + if (mEngine->GetButtonClick(PSP_CTRL_CIRCLE)){ + if (mObjects[mCurr] && mObjects[mCurr]->ButtonPressed()){ + DamagerDamaged * current = (DamagerDamaged *) mObjects[mCurr]; + if (!currentSource || !isOpponent(current,currentSource)){ + for (int i = 0; i < mCount; i++){ + DamagerDamaged * _current = (DamagerDamaged *) mObjects[i]; + if (isOpponent(current,_current)){ + currentSource = _current; + break; + } + } + } + if (currentSource){ + if (currentSource->damageSelecter == currentChoosingPlayer){ + if (isOpponent(current,currentSource)){ + if (!currentSource->dealOneDamage(current)){ + currentSource->removeDamagesTo(current); + } + } + } + }else{ + if (current->damageSelecter == currentChoosingPlayer){ + currentSource = current; + } + } + buttonOk = 0; + if (canStopDealDamages()) buttonOk = 1; + } + }else if (mEngine->GetButtonClick(PSP_CTRL_CROSS)){ + if (mObjects[mCurr] && mObjects[mCurr]->ButtonPressed()){ + DamagerDamaged * current = (DamagerDamaged *) mObjects[mCurr]; + if (current->damageSelecter == currentChoosingPlayer){ + currentSource = current; + } + } + }else if (mEngine->GetButtonClick(PSP_CTRL_SQUARE)){ + if (canStopDealDamages()){ + nextPlayer(); + //switch to next player or end of selection + } + }else{ + PlayGuiObjectController::CheckUserInput(dt); + } +} + +void DamageResolverLayer::Render(){ + if (!mCount) return; + JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); + mFont->SetBase(0); + mFont->SetScale(0.75); + + JRenderer * renderer = JRenderer::GetInstance(); + renderer->FillRect(0 ,0 , SCREEN_WIDTH , SCREEN_HEIGHT , ARGB(200,0,0,0)); + if (currentChoosingPlayer == game->currentPlayer){ + mFont->DrawString("Player 1", 0,0); + }else{ + mFont->DrawString("Player 2", 0,0); + } + if (currentSource){ + currentSource->RenderBig(10, 20); + mFont->DrawString("Current Damager:", 10, 5); + } + for (int i = 0; i < mCount; i++){ + ((DamagerDamaged *)mObjects[i])->Render(currentChoosingPlayer); + } + if (mObjects[mCurr]){ + ((DamagerDamaged *)mObjects[mCurr])->Render(currentChoosingPlayer); + } + + + if (buttonOk){ + mFont->DrawString("Damages Assigned, Click Square to Continue", 250, 5); + } +} diff --git a/projects/mtg/src/DamagerDamaged.cpp b/projects/mtg/src/DamagerDamaged.cpp index df507b21f..ca059c6e5 100644 --- a/projects/mtg/src/DamagerDamaged.cpp +++ b/projects/mtg/src/DamagerDamaged.cpp @@ -1,95 +1,95 @@ -#include "../include/debug.h" -#include "../include/DamagerDamaged.h" - - - - - DamagerDamaged::DamagerDamaged(CardGui * cardg, Player * _damageSelecter, bool _hasFocus):CardGui(0, cardg->card,cardg->defaultHeight,cardg->x,cardg->y, _hasFocus){ - mCount = 0; - damageSelecter = _damageSelecter; - damageToDeal = card->power; - } - - DamagerDamaged::~DamagerDamaged(){ - for (int i = 0; i < mCount; i++){ - delete damages[i]; - damages[i] = NULL; - } - } - - int DamagerDamaged::sumDamages(){ - int total = 0; - for (int i = 0; i < mCount; i++){ - total += damages[i]->damage; - } - return total; - } - - int DamagerDamaged::hasLethalDamage(){ - if (sumDamages() >= card->toughness) return 1; - return 0; - } - - int DamagerDamaged::dealOneDamage(DamagerDamaged * target){ - if (!damageToDeal) return 0; - damageToDeal--; - #if defined (WIN32) || defined (LINUX) - char buf[4096]; - sprintf(buf, "==========\n%s can still deal %i damages\n=============\n", card->getName(), damageToDeal); -OutputDebugString(buf); -#endif - return target->addDamage(1, this); - } - - int DamagerDamaged::addDamage(int damage, DamagerDamaged * source){ - for (int i = 0; i < mCount; i++){ - if (damages[i]->source == source->card){ - damages[i]->damage+= damage; - return damage; - } - } - damages[mCount] = NEW Damage(mCount, source->card, this->card,damage); - mCount++; - return damage; - } - - int DamagerDamaged::removeDamagesTo(DamagerDamaged * target){ - damageToDeal+= target->removeDamagesFrom(this); - return 1; - } - - int DamagerDamaged::removeDamagesFrom(DamagerDamaged * source){ - for (int i = 0; i < mCount; i++){ - if (damages[i]->source == source->card){ - int damage = damages[i]->damage; - delete(damages[i]); - damages[i] = NULL; - damages[i] = damages[mCount-1]; - mCount--; - return damage; - } - } - return 0; - } - - void DamagerDamaged::Render(Player * currentPlayer){ - JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); - mFont->SetBase(0); - mFont->SetScale(0.75); - CardGui::Render(); - char buf[4096]; - - if (currentPlayer != damageSelecter){ - if (hasLethalDamage()){ - mFont->DrawString("X",x,y); - } - mFont->SetColor(ARGB(255,255,0,0)); - sprintf(buf, "%i", sumDamages()); - mFont->DrawString(buf,x+5, y+5); - }else{ - mFont->SetColor(ARGB(255,0,0,255)); - sprintf(buf, "%i", damageToDeal); - mFont->DrawString(buf,x+5, y+5); - } - mFont->SetColor(ARGB(255,255,255,255)); - } \ No newline at end of file +#include "../include/debug.h" +#include "../include/DamagerDamaged.h" + + + + +DamagerDamaged::DamagerDamaged(CardGui * cardg, Player * _damageSelecter, bool _hasFocus):CardGui(0, cardg->card,cardg->defaultHeight,cardg->x,cardg->y, _hasFocus){ + mCount = 0; + damageSelecter = _damageSelecter; + damageToDeal = card->power; +} + +DamagerDamaged::~DamagerDamaged(){ + for (int i = 0; i < mCount; i++){ + delete damages[i]; + damages[i] = NULL; + } +} + +int DamagerDamaged::sumDamages(){ + int total = 0; + for (int i = 0; i < mCount; i++){ + total += damages[i]->damage; + } + return total; +} + +int DamagerDamaged::hasLethalDamage(){ + if (sumDamages() >= card->toughness) return 1; + return 0; +} + +int DamagerDamaged::dealOneDamage(DamagerDamaged * target){ + if (!damageToDeal) return 0; + damageToDeal--; +#if defined (WIN32) || defined (LINUX) + char buf[4096]; + sprintf(buf, "==========\n%s can still deal %i damages\n=============\n", card->getName(), damageToDeal); + OutputDebugString(buf); +#endif + return target->addDamage(1, this); +} + +int DamagerDamaged::addDamage(int damage, DamagerDamaged * source){ + for (int i = 0; i < mCount; i++){ + if (damages[i]->source == source->card){ + damages[i]->damage+= damage; + return damage; + } + } + damages[mCount] = NEW Damage(mCount, source->card, this->card,damage); + mCount++; + return damage; +} + +int DamagerDamaged::removeDamagesTo(DamagerDamaged * target){ + damageToDeal+= target->removeDamagesFrom(this); + return 1; +} + +int DamagerDamaged::removeDamagesFrom(DamagerDamaged * source){ + for (int i = 0; i < mCount; i++){ + if (damages[i]->source == source->card){ + int damage = damages[i]->damage; + delete(damages[i]); + damages[i] = NULL; + damages[i] = damages[mCount-1]; + mCount--; + return damage; + } + } + return 0; +} + +void DamagerDamaged::Render(Player * currentPlayer){ + JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); + mFont->SetBase(0); + mFont->SetScale(0.75); + CardGui::Render(); + char buf[4096]; + + if (currentPlayer != damageSelecter){ + if (hasLethalDamage()){ + mFont->DrawString("X",x,y); + } + mFont->SetColor(ARGB(255,255,0,0)); + sprintf(buf, "%i", sumDamages()); + mFont->DrawString(buf,x+5, y+5); + }else{ + mFont->SetColor(ARGB(255,0,0,255)); + sprintf(buf, "%i", damageToDeal); + mFont->DrawString(buf,x+5, y+5); + } + mFont->SetColor(ARGB(255,255,255,255)); +} diff --git a/projects/mtg/src/DeckDataWrapper.cpp b/projects/mtg/src/DeckDataWrapper.cpp index 4e5f72569..00eda5186 100644 --- a/projects/mtg/src/DeckDataWrapper.cpp +++ b/projects/mtg/src/DeckDataWrapper.cpp @@ -1,131 +1,131 @@ -#include "../include/DeckDataWrapper.h" -#include "../include/MTGDeck.h" - -DeckDataWrapper::DeckDataWrapper(MTGDeck * deck){ - parent = deck; - for (int i = 0; i <= MTG_NB_COLORS; i++){ - colors[i] = 0; - } - for (int i = 0; i < deck->totalCards(); i++){ - MTGCard * card = deck->_(i); - Add(card); - } - currentposition = 0; - currentColor = -1; -} - -void DeckDataWrapper::save(){ - parent->removeAll(); - map::iterator it; - for ( it=cards.begin() ; it != cards.end(); it++ ){ - MTGCard * current = (*it).first; - for (int i = 0; i < (*it).second; i++){ - parent->add(current); - } - } - parent->save(); -} - - -DeckDataWrapper::~DeckDataWrapper(){ - SAFE_DELETE(parent); -} - -void DeckDataWrapper::updateCounts(MTGCard * card, int removed){ - if (!card){ - for (int i = 0; i < MTG_NB_COLORS+1; i++){ - colors[i] = 0; - } - map::iterator it; - for ( it=cards.begin() ; it != cards.end(); it++ ){ - MTGCard * current = (*it).first; - colors[MTG_NB_COLORS] += (*it).second; - for (int i = 0; i < MTG_NB_COLORS; i++){ - if (current->hasColor(i)) colors[i]+=(*it).second; - } - } - }else{ - int increment = 1; - if (removed) increment = -1; - colors[MTG_NB_COLORS] += increment; - for (int i = 0; i < MTG_NB_COLORS; i++){ - if (card->hasColor(i)) colors[i]+=increment; - } - } -} - -int DeckDataWrapper::Add(MTGCard * card){ - if(cards.find(card) == cards.end()){ - cards[card] = 1; - }else{ - cards[card]++; - } - updateCounts(card); - return cards[card]; -} - -int DeckDataWrapper::Remove(MTGCard * card){ - if(cards.find(card) == cards.end() || cards[card] == 0) return 0; - cards[card]--; - updateCounts(card,1); - return 1; -} - -MTGCard * DeckDataWrapper::getNext(MTGCard * previous, int color){ - map::iterator it; - - it = cards.find(previous); - int found = 0; - - while(1){ - if (it == cards.end()){ - it = cards.begin(); - }else{ - it++; - } - if (it == cards.end()) return NULL; - MTGCard * card = (*it).first; - if (card == previous) return NULL; - if ((*it).second >0 && (color ==-1 || card->hasColor(color))){ - return card; - } - } -} - -MTGCard * DeckDataWrapper::getPrevious(MTGCard * next, int color){ - map::iterator it; - it = cards.find(next); - int found = 0; - - while(1){ - if (it == cards.begin()){ - it = cards.end(); - }else{ - it--; - } - if (it == cards.end()) return NULL; - MTGCard * card = (*it).first; - if (card == next) return NULL; - if ((*it).second >0 && (color ==-1 || card->hasColor(color))){ - return card; - } - } -} - -void DeckDataWrapper::updateCurrentPosition(MTGCard * currentCard, int color){ - currentposition = 0; - MTGCard * next = getNext(NULL,color); - while (next){ - currentposition+=cards[next]; - if (next == currentCard){ - next = NULL; - }else{ - next = getNext(next,color); - } - } -} - -int DeckDataWrapper::getCount(int color){ - if (color == -1) return colors[MTG_NB_COLORS]; - return colors[color]; -} \ No newline at end of file +#include "../include/DeckDataWrapper.h" +#include "../include/MTGDeck.h" + +DeckDataWrapper::DeckDataWrapper(MTGDeck * deck){ + parent = deck; + for (int i = 0; i <= MTG_NB_COLORS; i++){ + colors[i] = 0; + } + for (int i = 0; i < deck->totalCards(); i++){ + MTGCard * card = deck->_(i); + Add(card); + } + currentposition = 0; + currentColor = -1; +} + +void DeckDataWrapper::save(){ + parent->removeAll(); + map::iterator it; + for ( it=cards.begin() ; it != cards.end(); it++ ){ + MTGCard * current = (*it).first; + for (int i = 0; i < (*it).second; i++){ + parent->add(current); + } + } + parent->save(); +} + + +DeckDataWrapper::~DeckDataWrapper(){ + SAFE_DELETE(parent); +} + +void DeckDataWrapper::updateCounts(MTGCard * card, int removed){ + if (!card){ + for (int i = 0; i < MTG_NB_COLORS+1; i++){ + colors[i] = 0; + } + map::iterator it; + for ( it=cards.begin() ; it != cards.end(); it++ ){ + MTGCard * current = (*it).first; + colors[MTG_NB_COLORS] += (*it).second; + for (int i = 0; i < MTG_NB_COLORS; i++){ + if (current->hasColor(i)) colors[i]+=(*it).second; + } + } + }else{ + int increment = 1; + if (removed) increment = -1; + colors[MTG_NB_COLORS] += increment; + for (int i = 0; i < MTG_NB_COLORS; i++){ + if (card->hasColor(i)) colors[i]+=increment; + } + } +} + +int DeckDataWrapper::Add(MTGCard * card){ + if(cards.find(card) == cards.end()){ + cards[card] = 1; + }else{ + cards[card]++; + } + updateCounts(card); + return cards[card]; +} + +int DeckDataWrapper::Remove(MTGCard * card){ + if(cards.find(card) == cards.end() || cards[card] == 0) return 0; + cards[card]--; + updateCounts(card,1); + return 1; +} + +MTGCard * DeckDataWrapper::getNext(MTGCard * previous, int color){ + map::iterator it; + + it = cards.find(previous); + int found = 0; + + while(1){ + if (it == cards.end()){ + it = cards.begin(); + }else{ + it++; + } + if (it == cards.end()) return NULL; + MTGCard * card = (*it).first; + if (card == previous) return NULL; + if ((*it).second >0 && (color ==-1 || card->hasColor(color))){ + return card; + } + } +} + +MTGCard * DeckDataWrapper::getPrevious(MTGCard * next, int color){ + map::iterator it; + it = cards.find(next); + int found = 0; + + while(1){ + if (it == cards.begin()){ + it = cards.end(); + }else{ + it--; + } + if (it == cards.end()) return NULL; + MTGCard * card = (*it).first; + if (card == next) return NULL; + if ((*it).second >0 && (color ==-1 || card->hasColor(color))){ + return card; + } + } +} + +void DeckDataWrapper::updateCurrentPosition(MTGCard * currentCard, int color){ + currentposition = 0; + MTGCard * next = getNext(NULL,color); + while (next){ + currentposition+=cards[next]; + if (next == currentCard){ + next = NULL; + }else{ + next = getNext(next,color); + } + } +} + +int DeckDataWrapper::getCount(int color){ + if (color == -1) return colors[MTG_NB_COLORS]; + return colors[color]; +} diff --git a/projects/mtg/src/DuelLayers.cpp b/projects/mtg/src/DuelLayers.cpp index 63efe0624..f1873494c 100644 --- a/projects/mtg/src/DuelLayers.cpp +++ b/projects/mtg/src/DuelLayers.cpp @@ -1,63 +1,63 @@ -#include "../include/debug.h" -#include "../include/DuelLayers.h" -#include "../include/MTGRules.h" -#include "../include/DamageResolverLayer.h" - - - -void DuelLayers::init(){ - +#include "../include/debug.h" +#include "../include/DuelLayers.h" +#include "../include/MTGRules.h" +#include "../include/DamageResolverLayer.h" - //0 Stack Layer - ActionStack * mActionStack = NEW ActionStack(0, GameObserver::GetInstance()); - - //Damage Resolver - DamageResolverLayer * mDamageResolver = NEW DamageResolverLayer(1, GameObserver::GetInstance()); - - //1 Action Layer - GuiLayer * actionLayer = NEW ActionLayer(2, GameObserver::GetInstance()); - MTGGamePhase * phaseManager = NEW MTGGamePhase(actionLayer->getMaxId()); - actionLayer->Add(phaseManager); - //Add Magic Specific Rules - actionLayer->Add(NEW MTGAttackRule(-1)); - actionLayer->Add(NEW MTGBlockRule(-1)); - actionLayer->Add(NEW MTGLegendRule(-1)); - actionLayer->Add(NEW MTGPersistRule(-1)); - //2 Hand Layer - MTGGuiHand * mGuiHand = NEW MTGGuiHand(3, GameObserver::GetInstance()); - //3 Game - MTGGuiPlay * play = NEW MTGGuiPlay(4, GameObserver::GetInstance()); +void DuelLayers::init(){ + + + //0 Stack Layer + ActionStack * mActionStack = NEW ActionStack(0, GameObserver::GetInstance()); + + //Damage Resolver + DamageResolverLayer * mDamageResolver = NEW DamageResolverLayer(1, GameObserver::GetInstance()); + + //1 Action Layer + GuiLayer * actionLayer = NEW ActionLayer(2, GameObserver::GetInstance()); + MTGGamePhase * phaseManager = NEW MTGGamePhase(actionLayer->getMaxId()); + actionLayer->Add(phaseManager); + //Add Magic Specific Rules + actionLayer->Add(NEW MTGAttackRule(-1)); + actionLayer->Add(NEW MTGBlockRule(-1)); + actionLayer->Add(NEW MTGLegendRule(-1)); + actionLayer->Add(NEW MTGPersistRule(-1)); + + //2 Hand Layer + MTGGuiHand * mGuiHand = NEW MTGGuiHand(3, GameObserver::GetInstance()); + + //3 Game + MTGGuiPlay * play = NEW MTGGuiPlay(4, GameObserver::GetInstance()); + + Add(mActionStack); + Add(mDamageResolver); + Add(actionLayer); + Add(mGuiHand); + Add(play); + + +} + + +ActionStack * DuelLayers::stackLayer(){ + return ((ActionStack *) (objects[0])); +} + +DamageResolverLayer * DuelLayers::combatLayer(){ + return ((DamageResolverLayer *) (objects[1])); +} + +ActionLayer * DuelLayers::actionLayer(){ + return ((ActionLayer *) (objects[2])); +} + +MTGGuiHand * DuelLayers::handLayer(){ + return ((MTGGuiHand *) (objects[3])); +} +MTGGuiPlay * DuelLayers::playLayer(){ + return ((MTGGuiPlay *) (objects[4])); +} + + - Add(mActionStack); - Add(mDamageResolver); - Add(actionLayer); - Add(mGuiHand); - Add(play); - - -} - - -ActionStack * DuelLayers::stackLayer(){ - return ((ActionStack *) (objects[0])); -} - -DamageResolverLayer * DuelLayers::combatLayer(){ - return ((DamageResolverLayer *) (objects[1])); -} - -ActionLayer * DuelLayers::actionLayer(){ - return ((ActionLayer *) (objects[2])); -} - -MTGGuiHand * DuelLayers::handLayer(){ - return ((MTGGuiHand *) (objects[3])); -} -MTGGuiPlay * DuelLayers::playLayer(){ - return ((MTGGuiPlay *) (objects[4])); -} - - - diff --git a/projects/mtg/src/GameApp.cpp b/projects/mtg/src/GameApp.cpp index a2b153fe4..23a71cd82 100644 --- a/projects/mtg/src/GameApp.cpp +++ b/projects/mtg/src/GameApp.cpp @@ -1,250 +1,250 @@ - -#include "../include/debug.h" -#include -#include -#if defined (WIN32) || defined (LINUX) -#else -#include -#endif - - -#include "../include/GameApp.h" -#include "../include/Subtypes.h" -#include "../include/GameStateDeckViewer.h" -#include "../include/GameStateMenu.h" -#include "../include/GameStateDuel.h" -#include "../include/GameStateOptions.h" -#include "../include/GameStateShop.h" - - -const char * const GameState::menuTexts[]= {"--NEW--","Deck 1", "Deck 2", "Deck 3", "Deck 4", "Deck 5", "Deck 6"} ; -JResourceManager* GameApp::CommonRes = NEW JResourceManager(); -hgeParticleSystem* GameApp::Particles[] = {NULL,NULL,NULL,NULL,NULL,NULL}; -int GameApp::HasMusic = 1; - -GameState::GameState(GameApp* parent): mParent(parent) -{ - mEngine = JGE::GetInstance(); -} - - -GameApp::GameApp(): JApp() -{ - mScreenShotCount = 0; - - for (int i=0; i < MAX_STATE ; i++) - mGameStates[i] = NULL; - - mShowDebugInfo = false; - players[0] = 0; - players[1] = 0; - - - - -} - - -GameApp::~GameApp() -{ -} - - -void GameApp::Create() -{ -#if defined (WIN32) - _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); -#elif not defined (LINUX) - pspfpu_set_enable(0); //disable FPU Exceptions until we find where the FPU errors come from -#endif - //_CrtSetBreakAlloc(368); - LOG("starting Game"); - -//Test for Music files presence - std::ifstream file("Res/sound/Track0.mp3"); - if(file){ - file.close(); - }else{ - HasMusic = 0; - } - std::ifstream file2("Res/sound/Track1.mp3"); - if(file2){ - file2.close(); - }else{ - HasMusic = 0; - } - - -CommonRes->CreateTexture("graphics/menuicons.png"); -//Creating thes quad in this specific order allows us to have them in the correct order to call them by integer id -CommonRes->CreateQuad("c_artifact", "graphics/menuicons.png", 10 + 6*32, 32, 32, 32); -CommonRes->CreateQuad("c_green", "graphics/menuicons.png", 10 + 0*32, 32, 32, 32); -CommonRes->CreateQuad("c_blue", "graphics/menuicons.png", 10 + 1*32, 32, 32, 32); -CommonRes->CreateQuad("c_red", "graphics/menuicons.png", 10 + 3*32, 32, 32, 32); -CommonRes->CreateQuad("c_black", "graphics/menuicons.png", 10 + 2*32, 32, 32, 32); -CommonRes->CreateQuad("c_white", "graphics/menuicons.png", 10 + 4*32, 32, 32, 32); -CommonRes->CreateQuad("c_land", "graphics/menuicons.png", 10 + 5*32, 32, 32, 32); - - -CommonRes->CreateTexture("sets/back.jpg"); -CommonRes->CreateQuad("back", "sets/back.jpg", 0, 0, 200, 285); -CommonRes->CreateTexture("sets/back_thumb.jpg"); -CommonRes->CreateQuad("back_thumb", "sets/back_thumb.jpg", 0, 0, 45, 64); - -CommonRes->CreateTexture("graphics/particles.png"); -CommonRes->CreateQuad("particles", "graphics/particles.png", 0, 0, 32, 32); -CommonRes->GetQuad("particles")->SetHotSpot(16,16); - -CommonRes->LoadJLBFont("graphics/f3",16); -CommonRes->LoadJLBFont("graphics/magic",16); - - -//CommonRes->CreateTexture("graphics/interrupt.png"); -//CommonRes->CreateQuad("interrupt", "graphics/interrupt.png", 0, 0, 256, 128); - - cache = NEW TexturesCache(); - collection = NEW MTGAllCards(cache); - - -Particles[0] = NEW hgeParticleSystem("graphics/particle1.psi", CommonRes->GetQuad("particles")); -Particles[1] = NEW hgeParticleSystem("graphics/particle2.psi", CommonRes->GetQuad("particles")); -Particles[2] = NEW hgeParticleSystem("graphics/particle3.psi", CommonRes->GetQuad("particles")); -Particles[3] = NEW hgeParticleSystem("graphics/particle4.psi", CommonRes->GetQuad("particles")); -Particles[4] = NEW hgeParticleSystem("graphics/particle5.psi", CommonRes->GetQuad("particles")); -Particles[5] = NEW hgeParticleSystem("graphics/particle7.psi", CommonRes->GetQuad("particles")); - - mGameStates[GAME_STATE_DECK_VIEWER] = NEW GameStateDeckViewer(this); - mGameStates[GAME_STATE_DECK_VIEWER]->Create(); - - mGameStates[GAME_STATE_MENU] = NEW GameStateMenu(this); - mGameStates[GAME_STATE_MENU]->Create(); - - - mGameStates[GAME_STATE_DUEL] = NEW GameStateDuel(this); - mGameStates[GAME_STATE_DUEL]->Create(); - - mGameStates[GAME_STATE_SHOP] = NEW GameStateShop(this); - mGameStates[GAME_STATE_SHOP]->Create(); - - mGameStates[GAME_STATE_OPTIONS] = NEW GameStateOptions(this); - mGameStates[GAME_STATE_OPTIONS]->Create(); - - - - //mGameStates[GAME_STATE_GAME] = NEW GameStateGAME(this); - - mCurrentState = NULL; - mNextState = mGameStates[GAME_STATE_MENU]; - - - -} - - -void GameApp::LoadGameStates() -{ - - //mGameStates[GAME_STATE_MENU]->Create(); - //mGameStates[GAME_STATE_GAME]->Create(); - -} - - -void GameApp::Destroy() -{ - LOG("==Destroying GameApp=="); - for (int i=GAME_STATE_MENU;i<=MAX_STATE-1;i++) - { - if (mGameStates[i]){ - mGameStates[i]->Destroy(); - delete mGameStates[i]; - } - } - - for (int i= 0; i < 6; i++){ - delete Particles[i]; - } - - if (collection){ - collection->destroyAllCards(); - delete collection; - } - if (cache) delete cache; - - if (CommonRes) delete CommonRes; - - GameOptions::Destroy(); - - if (Subtypes::subtypesList) delete Subtypes::subtypesList; - if (MtgSets::SetsList) delete MtgSets::SetsList; - LOG("==Destroying GameApp Successful=="); - -} - - - -void GameApp::Update() -{ - - JGE* mEngine = JGE::GetInstance(); - if (mEngine->GetButtonState(PSP_CTRL_START) && mEngine->GetButtonClick(PSP_CTRL_TRIANGLE)) - { - char s[80]; - sprintf(s, "ms0:/psp/photo/MTG%d.png", mScreenShotCount++); - JRenderer::GetInstance()->ScreenShot(s); - } - //Exit when START and X ARE PRESSED SIMULTANEOUSLY - if (mEngine->GetButtonState(PSP_CTRL_START) && mEngine->GetButtonState(PSP_CTRL_CROSS)){ - mEngine->End(); - return; - } - - - - float dt = mEngine->GetDelta(); - if (dt > 35.0f) // min 30 FPS ;) - dt = 35.0f; - - if (mCurrentState != NULL) - mCurrentState->Update(dt); - - if (mNextState != NULL) - { - if (mCurrentState != NULL) - mCurrentState->End(); - - mCurrentState = mNextState; - mCurrentState->Start(); - - mNextState = NULL; - } - - - -} - - -void GameApp::Render() -{ - - if (mCurrentState != NULL) - { - mCurrentState->Render(); - } - - -} - -void GameApp::SetNextState(int state) -{ - mNextState = mGameStates[state]; -} - -void GameApp::Pause(){ - -} - -void GameApp::Resume(){ - -} - + +#include "../include/debug.h" +#include +#include +#if defined (WIN32) || defined (LINUX) +#else +#include +#endif + + +#include "../include/GameApp.h" +#include "../include/Subtypes.h" +#include "../include/GameStateDeckViewer.h" +#include "../include/GameStateMenu.h" +#include "../include/GameStateDuel.h" +#include "../include/GameStateOptions.h" +#include "../include/GameStateShop.h" + + +const char * const GameState::menuTexts[]= {"--NEW--","Deck 1", "Deck 2", "Deck 3", "Deck 4", "Deck 5", "Deck 6"} ; +JResourceManager* GameApp::CommonRes = NEW JResourceManager(); +hgeParticleSystem* GameApp::Particles[] = {NULL,NULL,NULL,NULL,NULL,NULL}; +int GameApp::HasMusic = 1; + +GameState::GameState(GameApp* parent): mParent(parent) +{ + mEngine = JGE::GetInstance(); +} + + +GameApp::GameApp(): JApp() +{ + mScreenShotCount = 0; + + for (int i=0; i < MAX_STATE ; i++) + mGameStates[i] = NULL; + + mShowDebugInfo = false; + players[0] = 0; + players[1] = 0; + + + + +} + + +GameApp::~GameApp() +{ +} + + +void GameApp::Create() +{ +#if defined (WIN32) + _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); +#elif not defined (LINUX) + pspfpu_set_enable(0); //disable FPU Exceptions until we find where the FPU errors come from +#endif + //_CrtSetBreakAlloc(368); + LOG("starting Game"); + + //Test for Music files presence + std::ifstream file("Res/sound/Track0.mp3"); + if(file){ + file.close(); + }else{ + HasMusic = 0; + } + std::ifstream file2("Res/sound/Track1.mp3"); + if(file2){ + file2.close(); + }else{ + HasMusic = 0; + } + + + CommonRes->CreateTexture("graphics/menuicons.png"); + //Creating thes quad in this specific order allows us to have them in the correct order to call them by integer id + CommonRes->CreateQuad("c_artifact", "graphics/menuicons.png", 10 + 6*32, 32, 32, 32); + CommonRes->CreateQuad("c_green", "graphics/menuicons.png", 10 + 0*32, 32, 32, 32); + CommonRes->CreateQuad("c_blue", "graphics/menuicons.png", 10 + 1*32, 32, 32, 32); + CommonRes->CreateQuad("c_red", "graphics/menuicons.png", 10 + 3*32, 32, 32, 32); + CommonRes->CreateQuad("c_black", "graphics/menuicons.png", 10 + 2*32, 32, 32, 32); + CommonRes->CreateQuad("c_white", "graphics/menuicons.png", 10 + 4*32, 32, 32, 32); + CommonRes->CreateQuad("c_land", "graphics/menuicons.png", 10 + 5*32, 32, 32, 32); + + + CommonRes->CreateTexture("sets/back.jpg"); + CommonRes->CreateQuad("back", "sets/back.jpg", 0, 0, 200, 285); + CommonRes->CreateTexture("sets/back_thumb.jpg"); + CommonRes->CreateQuad("back_thumb", "sets/back_thumb.jpg", 0, 0, 45, 64); + + CommonRes->CreateTexture("graphics/particles.png"); + CommonRes->CreateQuad("particles", "graphics/particles.png", 0, 0, 32, 32); + CommonRes->GetQuad("particles")->SetHotSpot(16,16); + + CommonRes->LoadJLBFont("graphics/f3",16); + CommonRes->LoadJLBFont("graphics/magic",16); + + + //CommonRes->CreateTexture("graphics/interrupt.png"); + //CommonRes->CreateQuad("interrupt", "graphics/interrupt.png", 0, 0, 256, 128); + + cache = NEW TexturesCache(); + collection = NEW MTGAllCards(cache); + + + Particles[0] = NEW hgeParticleSystem("graphics/particle1.psi", CommonRes->GetQuad("particles")); + Particles[1] = NEW hgeParticleSystem("graphics/particle2.psi", CommonRes->GetQuad("particles")); + Particles[2] = NEW hgeParticleSystem("graphics/particle3.psi", CommonRes->GetQuad("particles")); + Particles[3] = NEW hgeParticleSystem("graphics/particle4.psi", CommonRes->GetQuad("particles")); + Particles[4] = NEW hgeParticleSystem("graphics/particle5.psi", CommonRes->GetQuad("particles")); + Particles[5] = NEW hgeParticleSystem("graphics/particle7.psi", CommonRes->GetQuad("particles")); + + mGameStates[GAME_STATE_DECK_VIEWER] = NEW GameStateDeckViewer(this); + mGameStates[GAME_STATE_DECK_VIEWER]->Create(); + + mGameStates[GAME_STATE_MENU] = NEW GameStateMenu(this); + mGameStates[GAME_STATE_MENU]->Create(); + + + mGameStates[GAME_STATE_DUEL] = NEW GameStateDuel(this); + mGameStates[GAME_STATE_DUEL]->Create(); + + mGameStates[GAME_STATE_SHOP] = NEW GameStateShop(this); + mGameStates[GAME_STATE_SHOP]->Create(); + + mGameStates[GAME_STATE_OPTIONS] = NEW GameStateOptions(this); + mGameStates[GAME_STATE_OPTIONS]->Create(); + + + + //mGameStates[GAME_STATE_GAME] = NEW GameStateGAME(this); + + mCurrentState = NULL; + mNextState = mGameStates[GAME_STATE_MENU]; + + + +} + + +void GameApp::LoadGameStates() +{ + + //mGameStates[GAME_STATE_MENU]->Create(); + //mGameStates[GAME_STATE_GAME]->Create(); + +} + + +void GameApp::Destroy() +{ + LOG("==Destroying GameApp=="); + for (int i=GAME_STATE_MENU;i<=MAX_STATE-1;i++) + { + if (mGameStates[i]){ + mGameStates[i]->Destroy(); + delete mGameStates[i]; + } + } + + for (int i= 0; i < 6; i++){ + delete Particles[i]; + } + + if (collection){ + collection->destroyAllCards(); + delete collection; + } + if (cache) delete cache; + + if (CommonRes) delete CommonRes; + + GameOptions::Destroy(); + + if (Subtypes::subtypesList) delete Subtypes::subtypesList; + if (MtgSets::SetsList) delete MtgSets::SetsList; + LOG("==Destroying GameApp Successful=="); + +} + + + +void GameApp::Update() +{ + + JGE* mEngine = JGE::GetInstance(); + if (mEngine->GetButtonState(PSP_CTRL_START) && mEngine->GetButtonClick(PSP_CTRL_TRIANGLE)) + { + char s[80]; + sprintf(s, "ms0:/psp/photo/MTG%d.png", mScreenShotCount++); + JRenderer::GetInstance()->ScreenShot(s); + } + //Exit when START and X ARE PRESSED SIMULTANEOUSLY + if (mEngine->GetButtonState(PSP_CTRL_START) && mEngine->GetButtonState(PSP_CTRL_CROSS)){ + mEngine->End(); + return; + } + + + + float dt = mEngine->GetDelta(); + if (dt > 35.0f) // min 30 FPS ;) + dt = 35.0f; + + if (mCurrentState != NULL) + mCurrentState->Update(dt); + + if (mNextState != NULL) + { + if (mCurrentState != NULL) + mCurrentState->End(); + + mCurrentState = mNextState; + mCurrentState->Start(); + + mNextState = NULL; + } + + + +} + + +void GameApp::Render() +{ + + if (mCurrentState != NULL) + { + mCurrentState->Render(); + } + + +} + +void GameApp::SetNextState(int state) +{ + mNextState = mGameStates[state]; +} + +void GameApp::Pause(){ + +} + +void GameApp::Resume(){ + +} + diff --git a/projects/mtg/src/GameApp.h b/projects/mtg/src/GameApp.h index 2f0ea1932..c224f65a9 100644 --- a/projects/mtg/src/GameApp.h +++ b/projects/mtg/src/GameApp.h @@ -1,31 +1,31 @@ -//------------------------------------------------------------------------------------- -// -// JGE++ is a hardware accelerated 2D game SDK for PSP/Windows. -// -// Licensed under the BSD license, see LICENSE in JGE root for details. -// -// Copyright (c) 2007 James Hui (a.k.a. Dr.Watson) -// -//------------------------------------------------------------------------------------- - -#ifndef _GAMEAPP_H_ -#define _GAMEAPP_H_ - -#include - -class GameApp: public JApp -{ - -public: - GameApp(); - virtual ~GameApp(); - virtual void Create(); - virtual void Destroy(); - virtual void Update(); - virtual void Render(); - virtual void Pause(); - virtual void Resume(); - -}; - -#endif +//------------------------------------------------------------------------------------- +// +// JGE++ is a hardware accelerated 2D game SDK for PSP/Windows. +// +// Licensed under the BSD license, see LICENSE in JGE root for details. +// +// Copyright (c) 2007 James Hui (a.k.a. Dr.Watson) +// +//------------------------------------------------------------------------------------- + +#ifndef _GAMEAPP_H_ +#define _GAMEAPP_H_ + +#include + +class GameApp: public JApp +{ + + public: + GameApp(); + virtual ~GameApp(); + virtual void Create(); + virtual void Destroy(); + virtual void Update(); + virtual void Render(); + virtual void Pause(); + virtual void Resume(); + +}; + +#endif diff --git a/projects/mtg/src/GameLauncher.cpp b/projects/mtg/src/GameLauncher.cpp index 4367dedf6..59a324023 100644 --- a/projects/mtg/src/GameLauncher.cpp +++ b/projects/mtg/src/GameLauncher.cpp @@ -1,36 +1,36 @@ -//------------------------------------------------------------------------------------- -// -// JGE++ is a hardware accelerated 2D game SDK for PSP/Windows. -// -// Licensed under the BSD license, see LICENSE in JGE root for details. -// -// Copyright (c) 2007 James Hui (a.k.a. Dr.Watson) -// -//------------------------------------------------------------------------------------- -#include "../include/debug.h" -#include -#include - -#include "../include/GameApp.h" - - -//------------------------------------------------------------------------------------- -JApp* JGameLauncher::GetGameApp() -{ - return NEW GameApp(); -}; - - -//------------------------------------------------------------------------------------- -char *JGameLauncher::GetName() -{ - return strdup("Wagic"); -} - - -//------------------------------------------------------------------------------------- -u32 JGameLauncher::GetInitFlags() -{ - return JINIT_FLAG_NORMAL; -} - +//------------------------------------------------------------------------------------- +// +// JGE++ is a hardware accelerated 2D game SDK for PSP/Windows. +// +// Licensed under the BSD license, see LICENSE in JGE root for details. +// +// Copyright (c) 2007 James Hui (a.k.a. Dr.Watson) +// +//------------------------------------------------------------------------------------- +#include "../include/debug.h" +#include +#include + +#include "../include/GameApp.h" + + +//------------------------------------------------------------------------------------- +JApp* JGameLauncher::GetGameApp() +{ + return NEW GameApp(); +}; + + +//------------------------------------------------------------------------------------- +char *JGameLauncher::GetName() +{ + return strdup("Wagic"); +} + + +//------------------------------------------------------------------------------------- +u32 JGameLauncher::GetInitFlags() +{ + return JINIT_FLAG_NORMAL; +} + diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 984b5a4e5..9ae75163f 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -1,481 +1,481 @@ -#include "../include/debug.h" -#include "../include/GameObserver.h" - -#include "../include/GameOptions.h" -#include "../include/ConstraintResolver.h" -#include "../include/CardGui.h" -#include "../include/Damage.h" -#include "../include/DamageResolverLayer.h" - -#include - -GameObserver * GameObserver::mInstance = NULL; - - -GameObserver* GameObserver::GetInstance() -{ - - return mInstance; -} - -void GameObserver::EndInstance() -{ - - SAFE_DELETE(mInstance); -} - -void GameObserver::Init(Player * _players[], int _nbplayers){ - mInstance = NEW GameObserver(_players, _nbplayers); - mInstance->mLayers = NEW DuelLayers(); - mInstance->mLayers->init(); -} - - -GameObserver::GameObserver(Player * _players[], int _nb_players){ - int i; - - for (i =0; i < _nb_players;i ++){ - players[i] = _players[i]; - } - currentPlayer = players[0]; - currentActionPlayer = currentPlayer; - isInterrupting = NULL; - currentPlayerId = 0; - nbPlayers = _nb_players; - currentRound = 1; - currentGamePhase = -1; - targetChooser = NULL; - cardWaitingForTargets = NULL; - reaction = 0; - gameOver = NULL; - phaseRing = NEW PhaseRing(_players,_nb_players); -} - -void GameObserver::setGamePhaseManager(MTGGamePhase * _phases){ - gamePhaseManager = _phases; -} - -int GameObserver::getCurrentGamePhase(){ - return currentGamePhase; -} - - -Player * GameObserver::opponent(){ - int index = (currentPlayerId+1)%nbPlayers; - return players[index]; -} - -int GameObserver::enteringPhase(int phase){ - //TODO - return 0; -} - -void GameObserver::nextPlayer(){ - currentPlayerId = (currentPlayerId+1)%nbPlayers; - currentPlayer = players[currentPlayerId]; - currentActionPlayer = currentPlayer; - -} -void GameObserver::nextGamePhase(){ - phaseRing->forward(); - Phase * cPhase = phaseRing->getCurrentPhase(); - currentGamePhase = cPhase->id; - if (currentPlayer != cPhase->player) nextPlayer(); - - //init begin of turn - if (currentGamePhase == MTG_PHASE_BEFORE_BEGIN){ - cleanupPhase(); - currentPlayer->canPutLandsIntoPlay = 1; - mLayers->actionLayer()->Update(0); - return nextGamePhase(); - } - //manaBurn - if (currentGamePhase == MTG_PHASE_UNTAP || - currentGamePhase == MTG_PHASE_FIRSTMAIN || - currentGamePhase == MTG_PHASE_COMBATBEGIN || - currentGamePhase == MTG_PHASE_SECONDMAIN || - currentGamePhase == MTG_PHASE_ENDOFTURN - ){ - currentPlayer->manaBurn(); - } - - //After End of turn - if (currentGamePhase == MTG_PHASE_AFTER_EOT){ - //Auto Hand cleaning, in case the player didn't do it himself - while(currentPlayer->game->hand->nb_cards > 7){ - currentPlayer->game->putInGraveyard(currentPlayer->game->hand->cards[0]); - } - mLayers->stackLayer()->garbageCollect(); //clean stack history for this turn; - mLayers->actionLayer()->Update(0); - return nextGamePhase(); - } - - //Phase Specific actions - switch(currentGamePhase){ - case MTG_PHASE_UNTAP: - untapPhase(); - break; - case MTG_PHASE_DRAW: - mLayers->stackLayer()->addDraw(currentPlayer,1); - break; - default: - break; - } -} - -int GameObserver::cancelCurrentAction(){ - SAFE_DELETE(targetChooser); - return 1; -} - -void GameObserver::userRequestNextGamePhase(){ - if (mLayers->stackLayer()->getNext(NULL,0,NOT_RESOLVED)) return; - if (getCurrentTargetChooser()) return; - if (mLayers->combatLayer()->remainingDamageSteps) return; - //TODO CHECK POSSIBILITY - if (opponent()->isAI() || GameOptions::GetInstance()->values[OPTIONS_INTERRUPTATENDOFPHASE_OFFSET+currentGamePhase]){ - mLayers->stackLayer()->AddNextGamePhase(); - }else{ - nextGamePhase(); - } -} - - - -void GameObserver::startGame(int shuffle, int draw){ - int i; - for (i=0; igame->initGame(shuffle, draw); - } - phaseRing->goToPhase(MTG_PHASE_FIRSTMAIN, players[0]); - currentGamePhase = MTG_PHASE_FIRSTMAIN; -} - -void GameObserver::addObserver(MTGAbility * observer){ - mLayers->actionLayer()->Add(observer); -} - - -void GameObserver::removeObserver(ActionElement * observer){ - if (observer){ - observer->destroy(); - }else{ - //TODO log error - } - mLayers->actionLayer()->Remove(observer); -} - -GameObserver::~GameObserver(){ - LOG("==Destroying GameObserver=="); - SAFE_DELETE(targetChooser); - SAFE_DELETE(mLayers); - SAFE_DELETE(phaseRing); - LOG("==GameObserver Destroyed=="); - -} - -void GameObserver::Update(float dt){ - Player * player = currentPlayer; - if (currentGamePhase == MTG_PHASE_COMBATBLOCKERS){ - player = opponent(); - }else if (currentGamePhase == MTG_PHASE_COMBATDAMAGE){ - DamageResolverLayer * drl = mLayers->combatLayer(); - if (drl->currentChoosingPlayer && drl->mCount) player = drl->currentChoosingPlayer; - } - currentActionPlayer = player; - if (isInterrupting) player = isInterrupting; - mLayers->Update(dt,player); - stateEffects(); - oldGamePhase = currentGamePhase; - -} - -//applies damage to creatures after updates -//Players life test -void GameObserver::stateEffects(){ - for (int i =0; i < 2; i++){ - MTGGameZone * zone = players[i]->game->inPlay; - for (int j = zone->nb_cards-1 ; j>=0; j--){ - MTGCardInstance * card = zone->cards[j]; - card->afterDamage(); - } - } - - for (int i =0; i < 2; i++){ - if (players[i]->life <= 0) gameOver = players[i]; - } - -} - - -void GameObserver::Render(){ - mLayers->Render(); - if (targetChooser || mLayers->actionLayer()->isWaitingForAnswer()){ - JRenderer::GetInstance()->DrawRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT,ARGB(255,255,0,0)); - } - -} - - -void GameObserver::nextStep(){ - -} - - - - -void GameObserver::ButtonPressed (int controllerId, PlayGuiObject * _object){ - #if defined (WIN32) || defined (LINUX) -OutputDebugString("Click\n"); -#endif - int id = _object->GetId(); - if (id >=0){ - MTGCardInstance * card = ((CardGui *)_object)->card; - cardClick(card, card); - } - //if (id>= -6 && id <= -3){ - if (id== -5 || id == -3){ //TODO libraries ??? - GuiGameZone * zone = (GuiGameZone *)_object; - zone->toggleDisplay(); - } - if (id == -1 || id == -2){ -#if defined (WIN32) || defined (LINUX) -OutputDebugString("Click Player !\n"); -#endif - cardClick(NULL, ((GuiAvatar *)_object)->player); - } -} - -void GameObserver::stackObjectClicked(Interruptible * action){ - if (targetChooser != NULL){ -#if defined (WIN32) || defined (LINUX) - OutputDebugString("target chooser ok \n"); -#endif - int result = targetChooser->toggleTarget(action); - if (result == TARGET_OK_FULL){ -#if defined (WIN32) || defined (LINUX) - OutputDebugString("target chooser Full \n"); -#endif - cardClick(cardWaitingForTargets); - }else{ - return; - } - }else{ - reaction = mLayers->actionLayer()->isReactingToTargetClick(action); - if (reaction == -1) mLayers->actionLayer()->reactToTargetClick(action); - } -} - -void GameObserver::cardClick (MTGCardInstance * card, Targetable * object){ - LOG("==GameObserver::cardClick"); - if (card) {LOG(card->getName())}; - Player * clickedPlayer = NULL; - if (!card) clickedPlayer = ((Player *)object); - if (targetChooser != NULL){ - int result; - if (card) { - if (card == cardWaitingForTargets){ - LOG("attempt to close targetting"); - int _result = targetChooser->ForceTargetListReady(); - if (_result){ - result = TARGET_OK_FULL; - }else{ - - LOG("...but we cant!\n"); - result = targetChooser->targetsReadyCheck(); - } - }else{ - result = targetChooser->toggleTarget(card); - } - }else{ - result = targetChooser->toggleTarget(clickedPlayer); - } - if (result == TARGET_OK_FULL){ - card = cardWaitingForTargets; - }else{ - return; - } - } - - if (card){ - reaction = mLayers->actionLayer()->isReactingToClick(card); - if (reaction == -1) mLayers->actionLayer()->reactToClick(card); - }else{ - reaction = mLayers->actionLayer()->isReactingToTargetClick(object); - if (reaction == -1) mLayers->actionLayer()->reactToTargetClick(object); - } - - if (reaction != -1){ - if (!card) return; - if (currentlyActing()->game->hand->hasCard(card)){ - //Current player's hand - if (canPutInPlay(card)){ - putInPlay(card); - if (card->hasType("land")){ - currentPlayer->canPutLandsIntoPlay--; - } - }else if (currentPlayer->game->hand->hasCard(card)){ //Current player's hand - if (currentGamePhase == MTG_PHASE_CLEANUP && currentPlayer->game->hand->nb_cards > 7){ - currentPlayer->game->putInGraveyard(card); - } - } - }else if (reaction){ - if (reaction == 1){ - mLayers->actionLayer()->reactToClick(card); - }else{ - mLayers->actionLayer()->setMenuObject(object); - } - }else if (card->isTapped() && card->controller() == currentPlayer){ - int a = ConstraintResolver::untap(this, card); - } - } - - -} - - -TargetChooser * GameObserver::getCurrentTargetChooser(){ - TargetChooser * _tc = mLayers->actionLayer()->getCurrentTargetChooser(); - if (_tc) return _tc; - return targetChooser; -} - -//Check if it is possible to put a card into play -//TODO : improve according to spells in game... -int GameObserver::canPutInPlay(MTGCardInstance * card){ - Player * player = currentlyActing(); - LOG("CANPUTINPLAY- check if card belongs to current player\n"); - if (!player->game->hand->hasCard(card)) return 0; - LOG("CANPUTINPLAY- check if card is land or can be played\n"); - if (card->hasType("land")){ - LOG("CANPUTINPLAY- card is land - check if can be played\n"); - if (player == currentPlayer && currentPlayer->canPutLandsIntoPlay && (currentGamePhase == MTG_PHASE_FIRSTMAIN || currentGamePhase == MTG_PHASE_SECONDMAIN)){ - LOG("CANPUTINPLAY- Land, ok\n"); - return 1; - } - }else if ((card->hasType("instant")) || card->has(FLASH) || (player == currentPlayer && (currentGamePhase == MTG_PHASE_FIRSTMAIN || currentGamePhase == MTG_PHASE_SECONDMAIN))){ - LOG("CANPUTINPLAY- correct time to play\n"); - if (checkManaCost(card)){ - LOG("CANPUTINPLAY- ManaCost ok\n"); - if (targetListIsSet(card)){ -#ifdef LOG - LOG("CANPUTINPLAY- Targets chosen -> OK\n"); -#endif - return 1; - }else{ -#ifdef LOG - LOG("CANPUTINPLAY- Targets not chosen yet\n"); -#endif - return 0; - } - } - } - return 0; -} - - -void GameObserver::putInPlay(MTGCardInstance * card){ - Player * player = currentlyActing(); - ManaCost * previousManaPool = NEW ManaCost(player->getManaPool()); - player->getManaPool()->pay(card->getManaCost()); - ManaCost * spellCost = previousManaPool->Diff(player->getManaPool()); - delete previousManaPool; - if (card->hasType("land")){ - Spell * spell = NEW Spell(card); - player->game->putInZone(card, player->game->hand, player->game->stack); - spell->resolve(); - delete spellCost; - delete spell; - }else{ - if (targetChooser){ - mLayers->stackLayer()->addSpell(card,targetChooser->targets,targetChooser->cursor, spellCost); - delete targetChooser; - targetChooser = NULL; - }else{ - mLayers->stackLayer()->addSpell(card,NULL,0, spellCost); - } - player->game->putInZone(card, player->game->hand, player->game->stack); - - } - - -} - -/* Returns true if the card is in one of the player's play zone */ -int GameObserver::isInPlay(MTGCardInstance * card){ - for (int i = 0; i < 2; i++){ - if (players[i]->game->isInPlay(card)) return 1; - } - return 0; -} - -void GameObserver::draw(){ - //TODO checks to allow multiple draw, or no draw, etc... - currentPlayer->game->drawFromLibrary(); -} - -void GameObserver::cleanupPhase(){ - currentPlayer->cleanupPhase(); - opponent()->cleanupPhase(); -} - -void GameObserver::untapPhase(){ - currentPlayer->inPlay()->untapAll(); -} - - -int GameObserver::isACreature(MTGCardInstance * card){ - return card->isACreature(); -} - - -Player * GameObserver::currentlyActing(){ - if (isInterrupting) return isInterrupting; - return currentActionPlayer; -} - -int GameObserver::tryToTapOrUntap(MTGCardInstance * card){ - - int reaction = mLayers->actionLayer()->isReactingToClick(card); - if (reaction){ - if (reaction == 1){ - mLayers->actionLayer()->reactToClick(card); - }else{ - //TODO, what happens when several abilities react to the click ? - } - return reaction; - }else{ - if (card->isTapped() && card->controller() == currentPlayer){ - int a = ConstraintResolver::untap(this, card); - return a; - }else{ - //TODO Check Spells - //card->tap(); - return 0; - } - return 0; - } -} - -//TODO CORRECT THIS MESS -int GameObserver::targetListIsSet(MTGCardInstance * card){ - if (targetChooser == NULL){ - TargetChooserFactory tcf; - targetChooser = tcf.createTargetChooser(card); - cardWaitingForTargets = card; - if (targetChooser == NULL){ - return 1; - } - } - return (targetChooser->targetListSet()); -} - - -int GameObserver::checkManaCost(MTGCardInstance * card){ - ManaCost * playerMana = currentlyActing()->getManaPool(); - ManaCost * cost = card->getManaCost(); - if (playerMana->canAfford(cost)){ - return 1; - } - return 0; -} +#include "../include/debug.h" +#include "../include/GameObserver.h" + +#include "../include/GameOptions.h" +#include "../include/ConstraintResolver.h" +#include "../include/CardGui.h" +#include "../include/Damage.h" +#include "../include/DamageResolverLayer.h" + +#include + +GameObserver * GameObserver::mInstance = NULL; + + +GameObserver* GameObserver::GetInstance() +{ + + return mInstance; +} + +void GameObserver::EndInstance() +{ + + SAFE_DELETE(mInstance); +} + +void GameObserver::Init(Player * _players[], int _nbplayers){ + mInstance = NEW GameObserver(_players, _nbplayers); + mInstance->mLayers = NEW DuelLayers(); + mInstance->mLayers->init(); +} + + +GameObserver::GameObserver(Player * _players[], int _nb_players){ + int i; + + for (i =0; i < _nb_players;i ++){ + players[i] = _players[i]; + } + currentPlayer = players[0]; + currentActionPlayer = currentPlayer; + isInterrupting = NULL; + currentPlayerId = 0; + nbPlayers = _nb_players; + currentRound = 1; + currentGamePhase = -1; + targetChooser = NULL; + cardWaitingForTargets = NULL; + reaction = 0; + gameOver = NULL; + phaseRing = NEW PhaseRing(_players,_nb_players); +} + +void GameObserver::setGamePhaseManager(MTGGamePhase * _phases){ + gamePhaseManager = _phases; +} + +int GameObserver::getCurrentGamePhase(){ + return currentGamePhase; +} + + +Player * GameObserver::opponent(){ + int index = (currentPlayerId+1)%nbPlayers; + return players[index]; +} + +int GameObserver::enteringPhase(int phase){ + //TODO + return 0; +} + +void GameObserver::nextPlayer(){ + currentPlayerId = (currentPlayerId+1)%nbPlayers; + currentPlayer = players[currentPlayerId]; + currentActionPlayer = currentPlayer; + +} +void GameObserver::nextGamePhase(){ + phaseRing->forward(); + Phase * cPhase = phaseRing->getCurrentPhase(); + currentGamePhase = cPhase->id; + if (currentPlayer != cPhase->player) nextPlayer(); + + //init begin of turn + if (currentGamePhase == MTG_PHASE_BEFORE_BEGIN){ + cleanupPhase(); + currentPlayer->canPutLandsIntoPlay = 1; + mLayers->actionLayer()->Update(0); + return nextGamePhase(); + } + //manaBurn + if (currentGamePhase == MTG_PHASE_UNTAP || + currentGamePhase == MTG_PHASE_FIRSTMAIN || + currentGamePhase == MTG_PHASE_COMBATBEGIN || + currentGamePhase == MTG_PHASE_SECONDMAIN || + currentGamePhase == MTG_PHASE_ENDOFTURN + ){ + currentPlayer->manaBurn(); + } + + //After End of turn + if (currentGamePhase == MTG_PHASE_AFTER_EOT){ + //Auto Hand cleaning, in case the player didn't do it himself + while(currentPlayer->game->hand->nb_cards > 7){ + currentPlayer->game->putInGraveyard(currentPlayer->game->hand->cards[0]); + } + mLayers->stackLayer()->garbageCollect(); //clean stack history for this turn; + mLayers->actionLayer()->Update(0); + return nextGamePhase(); + } + + //Phase Specific actions + switch(currentGamePhase){ + case MTG_PHASE_UNTAP: + untapPhase(); + break; + case MTG_PHASE_DRAW: + mLayers->stackLayer()->addDraw(currentPlayer,1); + break; + default: + break; + } +} + +int GameObserver::cancelCurrentAction(){ + SAFE_DELETE(targetChooser); + return 1; +} + +void GameObserver::userRequestNextGamePhase(){ + if (mLayers->stackLayer()->getNext(NULL,0,NOT_RESOLVED)) return; + if (getCurrentTargetChooser()) return; + if (mLayers->combatLayer()->remainingDamageSteps) return; + //TODO CHECK POSSIBILITY + if (opponent()->isAI() || GameOptions::GetInstance()->values[OPTIONS_INTERRUPTATENDOFPHASE_OFFSET+currentGamePhase]){ + mLayers->stackLayer()->AddNextGamePhase(); + }else{ + nextGamePhase(); + } +} + + + +void GameObserver::startGame(int shuffle, int draw){ + int i; + for (i=0; igame->initGame(shuffle, draw); + } + phaseRing->goToPhase(MTG_PHASE_FIRSTMAIN, players[0]); + currentGamePhase = MTG_PHASE_FIRSTMAIN; +} + +void GameObserver::addObserver(MTGAbility * observer){ + mLayers->actionLayer()->Add(observer); +} + + +void GameObserver::removeObserver(ActionElement * observer){ + if (observer){ + observer->destroy(); + }else{ + //TODO log error + } + mLayers->actionLayer()->Remove(observer); +} + +GameObserver::~GameObserver(){ + LOG("==Destroying GameObserver=="); + SAFE_DELETE(targetChooser); + SAFE_DELETE(mLayers); + SAFE_DELETE(phaseRing); + LOG("==GameObserver Destroyed=="); + +} + +void GameObserver::Update(float dt){ + Player * player = currentPlayer; + if (currentGamePhase == MTG_PHASE_COMBATBLOCKERS){ + player = opponent(); + }else if (currentGamePhase == MTG_PHASE_COMBATDAMAGE){ + DamageResolverLayer * drl = mLayers->combatLayer(); + if (drl->currentChoosingPlayer && drl->mCount) player = drl->currentChoosingPlayer; + } + currentActionPlayer = player; + if (isInterrupting) player = isInterrupting; + mLayers->Update(dt,player); + stateEffects(); + oldGamePhase = currentGamePhase; + +} + +//applies damage to creatures after updates +//Players life test +void GameObserver::stateEffects(){ + for (int i =0; i < 2; i++){ + MTGGameZone * zone = players[i]->game->inPlay; + for (int j = zone->nb_cards-1 ; j>=0; j--){ + MTGCardInstance * card = zone->cards[j]; + card->afterDamage(); + } + } + + for (int i =0; i < 2; i++){ + if (players[i]->life <= 0) gameOver = players[i]; + } + +} + + +void GameObserver::Render(){ + mLayers->Render(); + if (targetChooser || mLayers->actionLayer()->isWaitingForAnswer()){ + JRenderer::GetInstance()->DrawRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT,ARGB(255,255,0,0)); + } + +} + + +void GameObserver::nextStep(){ + +} + + + + +void GameObserver::ButtonPressed (int controllerId, PlayGuiObject * _object){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("Click\n"); +#endif + int id = _object->GetId(); + if (id >=0){ + MTGCardInstance * card = ((CardGui *)_object)->card; + cardClick(card, card); + } + //if (id>= -6 && id <= -3){ + if (id== -5 || id == -3){ //TODO libraries ??? + GuiGameZone * zone = (GuiGameZone *)_object; + zone->toggleDisplay(); + } + if (id == -1 || id == -2){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("Click Player !\n"); +#endif + cardClick(NULL, ((GuiAvatar *)_object)->player); + } +} + +void GameObserver::stackObjectClicked(Interruptible * action){ + if (targetChooser != NULL){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("target chooser ok \n"); +#endif + int result = targetChooser->toggleTarget(action); + if (result == TARGET_OK_FULL){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("target chooser Full \n"); +#endif + cardClick(cardWaitingForTargets); + }else{ + return; + } + }else{ + reaction = mLayers->actionLayer()->isReactingToTargetClick(action); + if (reaction == -1) mLayers->actionLayer()->reactToTargetClick(action); + } +} + +void GameObserver::cardClick (MTGCardInstance * card, Targetable * object){ + LOG("==GameObserver::cardClick"); + if (card) {LOG(card->getName())}; + Player * clickedPlayer = NULL; + if (!card) clickedPlayer = ((Player *)object); + if (targetChooser != NULL){ + int result; + if (card) { + if (card == cardWaitingForTargets){ + LOG("attempt to close targetting"); + int _result = targetChooser->ForceTargetListReady(); + if (_result){ + result = TARGET_OK_FULL; + }else{ + + LOG("...but we cant!\n"); + result = targetChooser->targetsReadyCheck(); + } + }else{ + result = targetChooser->toggleTarget(card); + } + }else{ + result = targetChooser->toggleTarget(clickedPlayer); + } + if (result == TARGET_OK_FULL){ + card = cardWaitingForTargets; + }else{ + return; + } + } + + if (card){ + reaction = mLayers->actionLayer()->isReactingToClick(card); + if (reaction == -1) mLayers->actionLayer()->reactToClick(card); + }else{ + reaction = mLayers->actionLayer()->isReactingToTargetClick(object); + if (reaction == -1) mLayers->actionLayer()->reactToTargetClick(object); + } + + if (reaction != -1){ + if (!card) return; + if (currentlyActing()->game->hand->hasCard(card)){ + //Current player's hand + if (canPutInPlay(card)){ + putInPlay(card); + if (card->hasType("land")){ + currentPlayer->canPutLandsIntoPlay--; + } + }else if (currentPlayer->game->hand->hasCard(card)){ //Current player's hand + if (currentGamePhase == MTG_PHASE_CLEANUP && currentPlayer->game->hand->nb_cards > 7){ + currentPlayer->game->putInGraveyard(card); + } + } + }else if (reaction){ + if (reaction == 1){ + mLayers->actionLayer()->reactToClick(card); + }else{ + mLayers->actionLayer()->setMenuObject(object); + } + }else if (card->isTapped() && card->controller() == currentPlayer){ + int a = ConstraintResolver::untap(this, card); + } + } + + +} + + +TargetChooser * GameObserver::getCurrentTargetChooser(){ + TargetChooser * _tc = mLayers->actionLayer()->getCurrentTargetChooser(); + if (_tc) return _tc; + return targetChooser; +} + +//Check if it is possible to put a card into play +//TODO : improve according to spells in game... +int GameObserver::canPutInPlay(MTGCardInstance * card){ + Player * player = currentlyActing(); + LOG("CANPUTINPLAY- check if card belongs to current player\n"); + if (!player->game->hand->hasCard(card)) return 0; + LOG("CANPUTINPLAY- check if card is land or can be played\n"); + if (card->hasType("land")){ + LOG("CANPUTINPLAY- card is land - check if can be played\n"); + if (player == currentPlayer && currentPlayer->canPutLandsIntoPlay && (currentGamePhase == MTG_PHASE_FIRSTMAIN || currentGamePhase == MTG_PHASE_SECONDMAIN)){ + LOG("CANPUTINPLAY- Land, ok\n"); + return 1; + } + }else if ((card->hasType("instant")) || card->has(FLASH) || (player == currentPlayer && (currentGamePhase == MTG_PHASE_FIRSTMAIN || currentGamePhase == MTG_PHASE_SECONDMAIN))){ + LOG("CANPUTINPLAY- correct time to play\n"); + if (checkManaCost(card)){ + LOG("CANPUTINPLAY- ManaCost ok\n"); + if (targetListIsSet(card)){ +#ifdef LOG + LOG("CANPUTINPLAY- Targets chosen -> OK\n"); +#endif + return 1; + }else{ +#ifdef LOG + LOG("CANPUTINPLAY- Targets not chosen yet\n"); +#endif + return 0; + } + } + } + return 0; +} + + +void GameObserver::putInPlay(MTGCardInstance * card){ + Player * player = currentlyActing(); + ManaCost * previousManaPool = NEW ManaCost(player->getManaPool()); + player->getManaPool()->pay(card->getManaCost()); + ManaCost * spellCost = previousManaPool->Diff(player->getManaPool()); + delete previousManaPool; + if (card->hasType("land")){ + Spell * spell = NEW Spell(card); + player->game->putInZone(card, player->game->hand, player->game->stack); + spell->resolve(); + delete spellCost; + delete spell; + }else{ + if (targetChooser){ + mLayers->stackLayer()->addSpell(card,targetChooser->targets,targetChooser->cursor, spellCost); + delete targetChooser; + targetChooser = NULL; + }else{ + mLayers->stackLayer()->addSpell(card,NULL,0, spellCost); + } + player->game->putInZone(card, player->game->hand, player->game->stack); + + } + + +} + +/* Returns true if the card is in one of the player's play zone */ +int GameObserver::isInPlay(MTGCardInstance * card){ + for (int i = 0; i < 2; i++){ + if (players[i]->game->isInPlay(card)) return 1; + } + return 0; +} + +void GameObserver::draw(){ + //TODO checks to allow multiple draw, or no draw, etc... + currentPlayer->game->drawFromLibrary(); +} + +void GameObserver::cleanupPhase(){ + currentPlayer->cleanupPhase(); + opponent()->cleanupPhase(); +} + +void GameObserver::untapPhase(){ + currentPlayer->inPlay()->untapAll(); +} + + +int GameObserver::isACreature(MTGCardInstance * card){ + return card->isACreature(); +} + + +Player * GameObserver::currentlyActing(){ + if (isInterrupting) return isInterrupting; + return currentActionPlayer; +} + +int GameObserver::tryToTapOrUntap(MTGCardInstance * card){ + + int reaction = mLayers->actionLayer()->isReactingToClick(card); + if (reaction){ + if (reaction == 1){ + mLayers->actionLayer()->reactToClick(card); + }else{ + //TODO, what happens when several abilities react to the click ? + } + return reaction; + }else{ + if (card->isTapped() && card->controller() == currentPlayer){ + int a = ConstraintResolver::untap(this, card); + return a; + }else{ + //TODO Check Spells + //card->tap(); + return 0; + } + return 0; + } +} + +//TODO CORRECT THIS MESS +int GameObserver::targetListIsSet(MTGCardInstance * card){ + if (targetChooser == NULL){ + TargetChooserFactory tcf; + targetChooser = tcf.createTargetChooser(card); + cardWaitingForTargets = card; + if (targetChooser == NULL){ + return 1; + } + } + return (targetChooser->targetListSet()); +} + + +int GameObserver::checkManaCost(MTGCardInstance * card){ + ManaCost * playerMana = currentlyActing()->getManaPool(); + ManaCost * cost = card->getManaCost(); + if (playerMana->canAfford(cost)){ + return 1; + } + return 0; +} diff --git a/projects/mtg/src/GameOptions.cpp b/projects/mtg/src/GameOptions.cpp index 965d4086a..5f7b02494 100644 --- a/projects/mtg/src/GameOptions.cpp +++ b/projects/mtg/src/GameOptions.cpp @@ -1,61 +1,61 @@ -#include "../include/debug.h" -#include "../include/GameOptions.h" -#include -#include -#include -#include - -GameOptions* GameOptions::mInstance = NULL; - -GameOptions * GameOptions::GetInstance(){ - if (mInstance == NULL) - mInstance = NEW GameOptions(); - return mInstance; -} - -GameOptions::GameOptions(){ - for(int i = 0; i < MAX_OPTIONS; i++){ - values[i] = 0; - } - load(); -} - -int GameOptions::load(){ - std::ifstream file(OPTIONS_SAVEFILE); - std::string s; - if(file){ - for (int i = 0; i < MAX_OPTIONS; i++){ - if(std::getline(file,s)){ - values[i] = atoi(s.c_str()); - }else{ - //TODO error management - } - } - file.close(); - } - return 1; -} - -int GameOptions::save(){ - std::ofstream file(OPTIONS_SAVEFILE); - char writer[10]; - if (file){ - for (int i = 0; i < MAX_OPTIONS; i++){ - sprintf(writer,"%i\n", values[i]); - file< +#include +#include +#include + +GameOptions* GameOptions::mInstance = NULL; + +GameOptions * GameOptions::GetInstance(){ + if (mInstance == NULL) + mInstance = NEW GameOptions(); + return mInstance; +} + +GameOptions::GameOptions(){ + for(int i = 0; i < MAX_OPTIONS; i++){ + values[i] = 0; + } + load(); +} + +int GameOptions::load(){ + std::ifstream file(OPTIONS_SAVEFILE); + std::string s; + if(file){ + for (int i = 0; i < MAX_OPTIONS; i++){ + if(std::getline(file,s)){ + values[i] = atoi(s.c_str()); + }else{ + //TODO error management + } + } + file.close(); + } + return 1; +} + +int GameOptions::save(){ + std::ofstream file(OPTIONS_SAVEFILE); + char writer[10]; + if (file){ + for (int i = 0; i < MAX_OPTIONS; i++){ + sprintf(writer,"%i\n", values[i]); + file<ResetPrivateVRAM(); - renderer->EnableVSync(true); - - -#ifdef TESTSUITE -if (testSuite) delete testSuite; -testSuite = NEW TestSuite("Res/test/_tests.txt"); -#endif - - - mGamePhase = DUEL_CHOOSE_DECK1; - - mFont = GameApp::CommonRes->GetJLBFont("graphics/f3"); - mFont->SetBase(0); // using 2nd font - - - menu = NEW SimpleMenu(11,this,mFont,SCREEN_WIDTH/2-100,20,200); - menu->Add(12,"Back to main menu"); - menu->Add(13, "Cancel"); - - int decksneeded = 0; - - - for (int i = 0; i<2; i ++){ - if (mParent->players[i] == PLAYER_TYPE_HUMAN){ - if (!deckmenu){ - decksneeded = 1; - deckmenu = NEW SimpleMenu(1,this,mFont, 10 , 10, 100, "Choose a Deck"); - char buffer[100]; - for (int j=1; j<6; j++){ - sprintf(buffer, "Res/player/deck%i.txt",j); - std::ifstream file(buffer); - if(file){ - deckmenu->Add(j, GameState::menuTexts[j]); - file.close(); - decksneeded = 0; - } - } - } - } - } - - if (decksneeded) - mGamePhase = ERROR_NO_DECK; - - - -} - - -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); - }else{ - AIPlayerFactory playerCreator; - mPlayers[playerId] = playerCreator.createAIPlayer(mParent->collection,NULL); - deck[playerId] = mPlayers[playerId]->game; - } -} - -#ifdef TESTSUITE -void GameStateDuel::loadTestSuitePlayers(){ -OutputDebugString ("loading suite 1\n"); - if (!testSuite) return; - for (int i = 0; i < 2; i++){ - if (mPlayers[i]){ - delete mPlayers[i]; - } - mPlayers[i] = NEW TestSuiteAI(mParent->collection,testSuite, i); -OutputDebugString ("loading suite 2\n"); - deck[i] = mPlayers[i]->game; - } - - if (game) delete game; - game = NULL; - if (!game){ - GameObserver::Init(mPlayers, 2); -OutputDebugString ("loading suite 3\n"); - game = GameObserver::GetInstance(); -OutputDebugString ("loading suite 4\n"); - game->startGame(0,0); -OutputDebugString ("loading suite 5\n"); - } -} -#endif - -void GameStateDuel::End() -{ -#if defined (WIN32) || defined (LINUX) - OutputDebugString("Ending GamestateDuel\n"); -#endif - GameObserver::EndInstance(); - game = NULL; - SAFE_DELETE(deckmenu); - JRenderer::GetInstance()->EnableVSync(false); - for (int i = 0; i < 2; i++){ - SAFE_DELETE(mPlayers[i]); - SAFE_DELETE(deck[i]); - } - SAFE_DELETE(menu); -#ifdef TESTSUITE - SAFE_DELETE(testSuite); -#endif -} - - -void GameStateDuel::Update(float dt) -{ - if (mGamePhase == ERROR_NO_DECK){ - if (mEngine->GetButtonClick(PSP_CTRL_CIRCLE)){ - mParent->SetNextState(GAME_STATE_DECK_VIEWER); - } - }else if (mGamePhase == DUEL_CHOOSE_DECK1){ - if (mParent->players[0] == PLAYER_TYPE_HUMAN){ - deckmenu->Update(dt); - } -#ifdef TESTSUITE - else if (mParent->players[1] == PLAYER_TYPE_TESTSUITE){ - if (testSuite && testSuite->loadNext()){ - loadTestSuitePlayers(); - mGamePhase = DUEL_PLAY; - testSuite->initGame(); - char buf[4096]; - sprintf(buf, "nb cards in player2's graveyard : %i\n",mPlayers[1]->game->graveyard->nb_cards); - LOG(buf); - }else{ - mGamePhase = DUEL_END; - } - } -#endif - else{ - loadPlayer(0); - mGamePhase = DUEL_CHOOSE_DECK2; - } - }else if(mGamePhase == DUEL_CHOOSE_DECK2){ - if (mParent->players[1] == PLAYER_TYPE_HUMAN){ - deckmenu->Update(dt); - } - - else{ - loadPlayer(1); - mGamePhase = DUEL_PLAY; - } - - }else if (mGamePhase == DUEL_PLAY){ - if (!game){ - GameObserver::Init(mPlayers, 2); - game = GameObserver::GetInstance(); - game->startGame(); - } - game->Update(dt); - if (game->gameOver){ - if (!mPlayers[0]->isAI() && mPlayers[1]->isAI() && mPlayers[0]!= game->gameOver){ -#if defined (WIN32) || defined (LINUX) - char buf[4096]; - sprintf(buf, "%p - %p", mPlayers[0], game->gameOver); - OutputDebugString(buf); -#endif - PlayerData * playerdata = NEW PlayerData(mParent->collection); - playerdata->credits+= 500; - playerdata->save(); - delete playerdata; - } - mGamePhase = DUEL_END; -#ifdef TESTSUITE - if (mParent->players[1] == PLAYER_TYPE_TESTSUITE){ - if (testSuite->loadNext()){ - loadTestSuitePlayers(); - mGamePhase = DUEL_PLAY; - testSuite->initGame(); - }else{ - mGamePhase = DUEL_END; - } - }else if (mParent->players[0] == PLAYER_TYPE_CPU && mParent->players[1] == PLAYER_TYPE_CPU){ - End(); - Start(); - } -#endif - mFont->SetColor(ARGB(255,255,255,255)); - } - if (mEngine->GetButtonClick(PSP_CTRL_START)){ - mGamePhase = DUEL_MENU; - } - }else if (mGamePhase == DUEL_MENU){ - menu->Update(dt); - }else{ - if (mEngine->GetButtonClick(PSP_CTRL_CIRCLE)){ - mParent->SetNextState(GAME_STATE_MENU); - } - } - - -} - - -void GameStateDuel::Render() -{ - //Erase - JRenderer::GetInstance()->ClearScreen(ARGB(0,0,0,0)); - - - if (game) - game->Render(); - if (mGamePhase == DUEL_END){ - JRenderer::GetInstance()->ClearScreen(ARGB(200,0,0,0)); - char buffer[50]; - int p0life = mPlayers[0]->life; - if (!mPlayers[0]->isAI() && mPlayers[1]->isAI() ){ - if (game->gameOver !=mPlayers[0]){ - sprintf (buffer, "Victory! Congratulations, You earn 500 credits"); - }else{ - sprintf (buffer, "You have been defeated"); - } - }else{ - int winner = 2; - if (game->gameOver !=mPlayers[0]){ - 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) - 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); - }else if (mGamePhase == DUEL_MENU){ - menu->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; - case 13: - mGamePhase = DUEL_PLAY; - break; - } -} - - - - - - - +#include "../include/debug.h" +#include "../include/GameStateDuel.h" +#include "../include/utils.h" +#include "../include/AIPlayer.h" +#include "../include/PlayerData.h" + +#ifdef TESTSUITE +#include "../include/TestSuiteAI.h" +#endif + +GameStateDuel::GameStateDuel(GameApp* parent): GameState(parent) { + for (int i = 0; i<2; i ++){ + deck[i]=NULL; + mPlayers[i]=NULL; + } + + game = NULL; + deckmenu = NULL; + menu = NULL; +#ifdef TESTSUITE + testSuite = NULL; +#endif +} + +GameStateDuel::~GameStateDuel() { + End(); +} + +void GameStateDuel::Start() +{ + JRenderer * renderer = JRenderer::GetInstance(); + renderer->ResetPrivateVRAM(); + renderer->EnableVSync(true); + + +#ifdef TESTSUITE + if (testSuite) delete testSuite; + testSuite = NEW TestSuite("Res/test/_tests.txt"); +#endif + + + mGamePhase = DUEL_CHOOSE_DECK1; + + mFont = GameApp::CommonRes->GetJLBFont("graphics/f3"); + mFont->SetBase(0); // using 2nd font + + + menu = NEW SimpleMenu(11,this,mFont,SCREEN_WIDTH/2-100,20,200); + menu->Add(12,"Back to main menu"); + menu->Add(13, "Cancel"); + + int decksneeded = 0; + + + for (int i = 0; i<2; i ++){ + if (mParent->players[i] == PLAYER_TYPE_HUMAN){ + if (!deckmenu){ + decksneeded = 1; + deckmenu = NEW SimpleMenu(1,this,mFont, 10 , 10, 100, "Choose a Deck"); + char buffer[100]; + for (int j=1; j<6; j++){ + sprintf(buffer, "Res/player/deck%i.txt",j); + std::ifstream file(buffer); + if(file){ + deckmenu->Add(j, GameState::menuTexts[j]); + file.close(); + decksneeded = 0; + } + } + } + } + } + + if (decksneeded) + mGamePhase = ERROR_NO_DECK; + + + +} + + +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); + }else{ + AIPlayerFactory playerCreator; + mPlayers[playerId] = playerCreator.createAIPlayer(mParent->collection,NULL); + deck[playerId] = mPlayers[playerId]->game; + } +} + +#ifdef TESTSUITE +void GameStateDuel::loadTestSuitePlayers(){ + OutputDebugString ("loading suite 1\n"); + if (!testSuite) return; + for (int i = 0; i < 2; i++){ + if (mPlayers[i]){ + delete mPlayers[i]; + } + mPlayers[i] = NEW TestSuiteAI(mParent->collection,testSuite, i); + OutputDebugString ("loading suite 2\n"); + deck[i] = mPlayers[i]->game; + } + + if (game) delete game; + game = NULL; + if (!game){ + GameObserver::Init(mPlayers, 2); + OutputDebugString ("loading suite 3\n"); + game = GameObserver::GetInstance(); + OutputDebugString ("loading suite 4\n"); + game->startGame(0,0); + OutputDebugString ("loading suite 5\n"); + } +} +#endif + +void GameStateDuel::End() +{ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("Ending GamestateDuel\n"); +#endif + GameObserver::EndInstance(); + game = NULL; + SAFE_DELETE(deckmenu); + JRenderer::GetInstance()->EnableVSync(false); + for (int i = 0; i < 2; i++){ + SAFE_DELETE(mPlayers[i]); + SAFE_DELETE(deck[i]); + } + SAFE_DELETE(menu); +#ifdef TESTSUITE + SAFE_DELETE(testSuite); +#endif +} + + +void GameStateDuel::Update(float dt) +{ + if (mGamePhase == ERROR_NO_DECK){ + if (mEngine->GetButtonClick(PSP_CTRL_CIRCLE)){ + mParent->SetNextState(GAME_STATE_DECK_VIEWER); + } + }else if (mGamePhase == DUEL_CHOOSE_DECK1){ + if (mParent->players[0] == PLAYER_TYPE_HUMAN){ + deckmenu->Update(dt); + } +#ifdef TESTSUITE + else if (mParent->players[1] == PLAYER_TYPE_TESTSUITE){ + if (testSuite && testSuite->loadNext()){ + loadTestSuitePlayers(); + mGamePhase = DUEL_PLAY; + testSuite->initGame(); + char buf[4096]; + sprintf(buf, "nb cards in player2's graveyard : %i\n",mPlayers[1]->game->graveyard->nb_cards); + LOG(buf); + }else{ + mGamePhase = DUEL_END; + } + } +#endif + else{ + loadPlayer(0); + mGamePhase = DUEL_CHOOSE_DECK2; + } + }else if(mGamePhase == DUEL_CHOOSE_DECK2){ + if (mParent->players[1] == PLAYER_TYPE_HUMAN){ + deckmenu->Update(dt); + } + + else{ + loadPlayer(1); + mGamePhase = DUEL_PLAY; + } + + }else if (mGamePhase == DUEL_PLAY){ + if (!game){ + GameObserver::Init(mPlayers, 2); + game = GameObserver::GetInstance(); + game->startGame(); + } + game->Update(dt); + if (game->gameOver){ + if (!mPlayers[0]->isAI() && mPlayers[1]->isAI() && mPlayers[0]!= game->gameOver){ +#if defined (WIN32) || defined (LINUX) + char buf[4096]; + sprintf(buf, "%p - %p", mPlayers[0], game->gameOver); + OutputDebugString(buf); +#endif + PlayerData * playerdata = NEW PlayerData(mParent->collection); + playerdata->credits+= 500; + playerdata->save(); + delete playerdata; + } + mGamePhase = DUEL_END; +#ifdef TESTSUITE + if (mParent->players[1] == PLAYER_TYPE_TESTSUITE){ + if (testSuite->loadNext()){ + loadTestSuitePlayers(); + mGamePhase = DUEL_PLAY; + testSuite->initGame(); + }else{ + mGamePhase = DUEL_END; + } + }else if (mParent->players[0] == PLAYER_TYPE_CPU && mParent->players[1] == PLAYER_TYPE_CPU){ + End(); + Start(); + } +#endif + mFont->SetColor(ARGB(255,255,255,255)); + } + if (mEngine->GetButtonClick(PSP_CTRL_START)){ + mGamePhase = DUEL_MENU; + } + }else if (mGamePhase == DUEL_MENU){ + menu->Update(dt); + }else{ + if (mEngine->GetButtonClick(PSP_CTRL_CIRCLE)){ + mParent->SetNextState(GAME_STATE_MENU); + } + } + + +} + + +void GameStateDuel::Render() +{ + //Erase + JRenderer::GetInstance()->ClearScreen(ARGB(0,0,0,0)); + + + if (game) + game->Render(); + if (mGamePhase == DUEL_END){ + JRenderer::GetInstance()->ClearScreen(ARGB(200,0,0,0)); + char buffer[50]; + int p0life = mPlayers[0]->life; + if (!mPlayers[0]->isAI() && mPlayers[1]->isAI() ){ + if (game->gameOver !=mPlayers[0]){ + sprintf (buffer, "Victory! Congratulations, You earn 500 credits"); + }else{ + sprintf (buffer, "You have been defeated"); + } + }else{ + int winner = 2; + if (game->gameOver !=mPlayers[0]){ + 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) + 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); + }else if (mGamePhase == DUEL_MENU){ + menu->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; + case 13: + mGamePhase = DUEL_PLAY; + break; + } +} + + + + + + + diff --git a/projects/mtg/src/GameStateOptions.cpp b/projects/mtg/src/GameStateOptions.cpp index ef128611c..bd199dacc 100644 --- a/projects/mtg/src/GameStateOptions.cpp +++ b/projects/mtg/src/GameStateOptions.cpp @@ -1,118 +1,118 @@ -#include "../include/debug.h" -#include "../include/GameStateOptions.h" -#include "../include/GameApp.h" -#include "../include/OptionItem.h" -#include "../include/SimpleMenu.h" -#include "../include/GameOptions.h" - -GameStateOptions::GameStateOptions(GameApp* parent): GameState(parent) { - optionsList = NULL; - optionsMenu = NULL; -} - - -GameStateOptions::~GameStateOptions() { - -} - -void GameStateOptions::Start() -{ - 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)); - 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"); - optionsMenu->Add(2, "Back to Main Menu"); - optionsMenu->Add(3, "Cancel"); - -} - - -void GameStateOptions::End() -{ - JRenderer::GetInstance()->EnableVSync(false); - SAFE_DELETE(optionsList); -} - - -void GameStateOptions::Update(float dt) -{ - if (mState == SHOW_OPTIONS){ - if (mEngine->GetButtonClick(PSP_CTRL_START)){ - mState = SHOW_OPTIONS_MENU; - } - - optionsList->Update(dt); - }else{ - optionsMenu->Update(dt); - } - - -} - - -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", - "", - "Developped with the JGE++ Library", - "http://jge.khors.com", - "", - "this freeware app is not endorsed by Wizards of the Coast, Inc", - - }; - - const char * const MusicText[] = { - "", - "Music by Celestial Aeon Project, under Creative Commons License", - "Their music can be downloaded at http://www.jamendo.com" - }; - - - JLBFont * mFont = GameApp::CommonRes->GetJLBFont("graphics/f3"); - 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); - } - - if (GameApp::HasMusic){ - for (int i = 0; i < 3; i++){ - mFont->DrawString(MusicText[i],SCREEN_WIDTH/2, 40 +18*(8+i),JGETEXT_CENTER); - } - } - mFont->SetScale(1.f); - - if (mState == SHOW_OPTIONS_MENU){ - optionsMenu->Render(); - } - -} - - -void GameStateOptions::ButtonPressed(int controllerId, int controlId) - { - switch (controlId){ - case 1: - optionsList->save(); - case 2: - mParent->SetNextState(GAME_STATE_MENU); - break; - case 3: - mState = SHOW_OPTIONS; - break; - } -}; - - +#include "../include/debug.h" +#include "../include/GameStateOptions.h" +#include "../include/GameApp.h" +#include "../include/OptionItem.h" +#include "../include/SimpleMenu.h" +#include "../include/GameOptions.h" + +GameStateOptions::GameStateOptions(GameApp* parent): GameState(parent) { + optionsList = NULL; + optionsMenu = NULL; +} + + +GameStateOptions::~GameStateOptions() { + +} + +void GameStateOptions::Start() +{ + 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)); + 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"); + optionsMenu->Add(2, "Back to Main Menu"); + optionsMenu->Add(3, "Cancel"); + +} + + +void GameStateOptions::End() +{ + JRenderer::GetInstance()->EnableVSync(false); + SAFE_DELETE(optionsList); +} + + +void GameStateOptions::Update(float dt) +{ + if (mState == SHOW_OPTIONS){ + if (mEngine->GetButtonClick(PSP_CTRL_START)){ + mState = SHOW_OPTIONS_MENU; + } + + optionsList->Update(dt); + }else{ + optionsMenu->Update(dt); + } + + +} + + +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", + "", + "Developped with the JGE++ Library", + "http://jge.khors.com", + "", + "this freeware app is not endorsed by Wizards of the Coast, Inc", + + }; + + const char * const MusicText[] = { + "", + "Music by Celestial Aeon Project, under Creative Commons License", + "Their music can be downloaded at http://www.jamendo.com" + }; + + + JLBFont * mFont = GameApp::CommonRes->GetJLBFont("graphics/f3"); + 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); + } + + if (GameApp::HasMusic){ + for (int i = 0; i < 3; i++){ + mFont->DrawString(MusicText[i],SCREEN_WIDTH/2, 40 +18*(8+i),JGETEXT_CENTER); + } + } + mFont->SetScale(1.f); + + if (mState == SHOW_OPTIONS_MENU){ + optionsMenu->Render(); + } + +} + + +void GameStateOptions::ButtonPressed(int controllerId, int controlId) +{ + switch (controlId){ + case 1: + optionsList->save(); + case 2: + mParent->SetNextState(GAME_STATE_MENU); + break; + case 3: + mState = SHOW_OPTIONS; + break; + } +}; + + diff --git a/projects/mtg/src/GameStateShop.cpp b/projects/mtg/src/GameStateShop.cpp index 13783933d..3daf7d4ed 100644 --- a/projects/mtg/src/GameStateShop.cpp +++ b/projects/mtg/src/GameStateShop.cpp @@ -1,5 +1,5 @@ /* -The shop is where the player can buy cards, decks... + The shop is where the player can buy cards, decks... */ #include "../include/debug.h" #include @@ -12,7 +12,7 @@ GameStateShop::GameStateShop(GameApp* parent): GameState(parent) {} GameStateShop::~GameStateShop() { - //End(); TODO FIX THAT + //End(); TODO FIX THAT } void GameStateShop::Create(){ @@ -24,55 +24,55 @@ void GameStateShop::Create(){ 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. + 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++){ - if (mParent->collection->countBySet(i) > 100){ //Only sets with more than 100 cards can get boosters and starters - sets[nbsets] = i; - nbsets++; - } - } - if (nbsets){ - setId = sets[(rand() % nbsets)]; - }else{ - setId = (rand() % MtgSets::SetsList->nb_items); - } - JQuad * mBackThumb = GameApp::CommonRes->GetQuad("back_thumb"); - 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()); - shop->Add(starterBuffer,mBack,mBackThumb, 6000); - shop->Add(boosterBuffer,mBack,mBackThumb, 1900); + int sets[500]; + int nbsets = 0; + for (int i = 0; i < MtgSets::SetsList->nb_items; i++){ + if (mParent->collection->countBySet(i) > 100){ //Only sets with more than 100 cards can get boosters and starters + sets[nbsets] = i; + nbsets++; + } + } + if (nbsets){ + setId = sets[(rand() % nbsets)]; + }else{ + setId = (rand() % MtgSets::SetsList->nb_items); + } + JQuad * mBackThumb = GameApp::CommonRes->GetQuad("back_thumb"); + 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()); + shop->Add(starterBuffer,mBack,mBackThumb, 6000); + shop->Add(boosterBuffer,mBack,mBackThumb, 1900); for (int i = 0; i < 4; i++){ - shop->Add(mParent->collection->randomCardId()); - } + shop->Add(mParent->collection->randomCardId()); + } } void GameStateShop::End() { - JRenderer::GetInstance()->EnableVSync(false); - if (shop) - SAFE_DELETE(shop); - SAFE_DELETE(mBack); - if(bgTexture) - SAFE_DELETE(bgTexture); - if(mBg) - SAFE_DELETE(mBg); - if(menu) - SAFE_DELETE(menu); - + JRenderer::GetInstance()->EnableVSync(false); + if (shop) + SAFE_DELETE(shop); + SAFE_DELETE(mBack); + if(bgTexture) + SAFE_DELETE(bgTexture); + if(mBg) + SAFE_DELETE(mBg); + if(menu) + SAFE_DELETE(menu); + } void GameStateShop::Destroy(){ @@ -80,52 +80,52 @@ void GameStateShop::Destroy(){ void GameStateShop::Update(float dt) { - if (mStage == STAGE_SHOP_MENU){ - if (menu){ - menu->Update(dt); - }else{ - menu = NEW SimpleMenu(11,this,mFont,SCREEN_WIDTH/2-100,20,200); - menu->Add(12,"Save & Back to main menu"); - menu->Add(13, "Cancel"); - } - }else{ - if (mEngine->GetButtonClick(PSP_CTRL_START)){ - mStage = STAGE_SHOP_MENU; - } - if (shop) - shop->Update(dt); - } + if (mStage == STAGE_SHOP_MENU){ + if (menu){ + menu->Update(dt); + }else{ + menu = NEW SimpleMenu(11,this,mFont,SCREEN_WIDTH/2-100,20,200); + menu->Add(12,"Save & Back to main menu"); + menu->Add(13, "Cancel"); + } + }else{ + if (mEngine->GetButtonClick(PSP_CTRL_START)){ + mStage = STAGE_SHOP_MENU; + } + if (shop) + shop->Update(dt); + } } -void GameStateShop::Render() +void GameStateShop::Render() { //Erase JRenderer::GetInstance()->ClearScreen(ARGB(0,0,0,0)); - if (mBg)JRenderer::GetInstance()->RenderQuad(mBg,0,0); + if (mBg)JRenderer::GetInstance()->RenderQuad(mBg,0,0); if (shop) - shop->Render(); - if (mStage == STAGE_SHOP_MENU && menu){ - menu->Render(); - } + shop->Render(); + if (mStage == STAGE_SHOP_MENU && menu){ + menu->Render(); + } } void GameStateShop::ButtonPressed(int controllerId, int controlId) { - switch (controllerId){ - case 10: - shop->pricedialog(controlId); - break; - case 11: - if (controlId == 12){ - shop->saveAll(); - mParent->SetNextState(GAME_STATE_MENU); - }else{ - mStage = STAGE_SHOP_SHOP; - } - break; - } + switch (controllerId){ + case 10: + shop->pricedialog(controlId); + break; + case 11: + if (controlId == 12){ + shop->saveAll(); + mParent->SetNextState(GAME_STATE_MENU); + }else{ + mStage = STAGE_SHOP_SHOP; + } + break; + } } diff --git a/projects/mtg/src/GuiLayers.cpp b/projects/mtg/src/GuiLayers.cpp index 98bcd7e8e..026302021 100644 --- a/projects/mtg/src/GuiLayers.cpp +++ b/projects/mtg/src/GuiLayers.cpp @@ -5,7 +5,7 @@ GuiLayer::GuiLayer(int id, GameObserver* _game):JGuiController(id, NULL){ game = _game; modal = 0; - hasFocus = 0; + hasFocus = 0; } GuiLayer::~GuiLayer(){ @@ -13,7 +13,7 @@ GuiLayer::~GuiLayer(){ } int GuiLayer::getMaxId(){ - return mCount; + return mCount; } void GuiLayer::Update(float dt){ @@ -24,16 +24,16 @@ void GuiLayer::Update(float dt){ void GuiLayer::resetObjects(){ - for (int i=0;iFillRect(x0,y0,width,height/2,colors_up); renderer->FillRect(x0,y0+height/2,width,height/2,colors_down); - + // mEngine->DrawLine(0,y0,SCREEN_WIDTH,y0,ARGB(128,255,255,255)); // mEngine->DrawLine(0,y0+height,SCREEN_WIDTH,y0+height,ARGB(128,255,255,255)); } void GuiLayer::RenderMessageBackground(float y0, int height){ - RenderMessageBackground(0,y0,SCREEN_WIDTH, height); + RenderMessageBackground(0,y0,SCREEN_WIDTH, height); } @@ -73,14 +73,14 @@ void GuiLayer::setModal(int _modal){ int GuiLayer::getIndexOf(JGuiObject * object){ for (int i=0; iunstopableRenderInProgress()) - return 1; + return 1; } - return 0; + return 0; } void GuiLayers::Add(GuiLayer * layer){ - if (nbitems >=MAX_GUI_LAYERS || nbitems < 0){ - LOG("OUT OF BOUND IN GuiLayers Add !!!"); - return; - } + if (nbitems >=MAX_GUI_LAYERS || nbitems < 0){ + LOG("OUT OF BOUND IN GuiLayers Add !!!"); + return; + } objects[nbitems] = layer; nbitems++; } @@ -121,23 +121,23 @@ void GuiLayers::Remove(){ void GuiLayers::Update(float dt, Player * currentPlayer){ int i; int modal = 0; - int isAI = currentPlayer->isAI(); + int isAI = currentPlayer->isAI(); for (i=0; ihasFocus = 0; + objects[i]->hasFocus = 0; objects[i]->Update(dt); if (!isAI && !modal){ - objects[i]->hasFocus = 1; + objects[i]->hasFocus = 1; objects[i]->CheckUserInput(dt); modal = objects[i]->isModal(); } } - if (isAI){ - currentPlayer->Act(dt); - } + if (isAI){ + currentPlayer->Act(dt); + } } void GuiLayers::Render(){ for (int i=nbitems-1; i>=0; i--){ - objects[i]->Render(); + objects[i]->Render(); } } diff --git a/projects/mtg/src/GuiMessageBox.cpp b/projects/mtg/src/GuiMessageBox.cpp index abed3dcf4..6b620112f 100644 --- a/projects/mtg/src/GuiMessageBox.cpp +++ b/projects/mtg/src/GuiMessageBox.cpp @@ -2,60 +2,60 @@ void GuiMessageBox::CheckUserInput(){ - if (mEngine->GetButtonClick(mActionButton)) + if (mEngine->GetButtonClick(mActionButton)) + { + if (mObjects[mCurr] != NULL && mObjects[mCurr]->ButtonPressed()) { - if (mObjects[mCurr] != NULL && mObjects[mCurr]->ButtonPressed()) - { - if (mListener != NULL) - { - mListener->ButtonPressed(mId, mObjects[mCurr]->GetId()); - return; - } - } + if (mListener != NULL) + { + mListener->ButtonPressed(mId, mObjects[mCurr]->GetId()); + return; + } } - - if (mEngine->GetButtonState(PSP_CTRL_LEFT) || mEngine->GetButtonState(PSP_CTRL_UP) || mEngine->GetAnalogY()<64) - { - if (KeyRepeated(PSP_CTRL_UP, dt)) - { - int n = mCurr; - n--; - if (n<0) - { - if ((mStyle&JGUI_STYLE_WRAPPING)) - n = mCount-1; - else - n = 0; - } + } - if (n != mCurr && mObjects[mCurr] != NULL && mObjects[mCurr]->Leaving(PSP_CTRL_UP)) - { - mCurr = n; - mObjects[mCurr]->Entering(); - } - } - } - else if (mEngine->GetButtonState(PSP_CTRL_RIGHT) || mEngine->GetButtonState(PSP_CTRL_DOWN) || mEngine->GetAnalogY()>192) + if (mEngine->GetButtonState(PSP_CTRL_LEFT) || mEngine->GetButtonState(PSP_CTRL_UP) || mEngine->GetAnalogY()<64) + { + if (KeyRepeated(PSP_CTRL_UP, dt)) { - if (KeyRepeated(PSP_CTRL_DOWN, dt)) - { - int n = mCurr; - n++; - if (n>mCount-1) - { - if ((mStyle&JGUI_STYLE_WRAPPING)) - n = 0; - else - n = mCount-1; - } + int n = mCurr; + n--; + if (n<0) + { + if ((mStyle&JGUI_STYLE_WRAPPING)) + n = mCount-1; + else + n = 0; + } - if (n != mCurr && mObjects[mCurr] != NULL && mObjects[mCurr]->Leaving(PSP_CTRL_DOWN)) - { - mCurr = n; - mObjects[mCurr]->Entering(); - } - } + if (n != mCurr && mObjects[mCurr] != NULL && mObjects[mCurr]->Leaving(PSP_CTRL_UP)) + { + mCurr = n; + mObjects[mCurr]->Entering(); + } } - else - mLastKey = 0; + } + else if (mEngine->GetButtonState(PSP_CTRL_RIGHT) || mEngine->GetButtonState(PSP_CTRL_DOWN) || mEngine->GetAnalogY()>192) + { + if (KeyRepeated(PSP_CTRL_DOWN, dt)) + { + int n = mCurr; + n++; + if (n>mCount-1) + { + if ((mStyle&JGUI_STYLE_WRAPPING)) + n = 0; + else + n = mCount-1; + } + + if (n != mCurr && mObjects[mCurr] != NULL && mObjects[mCurr]->Leaving(PSP_CTRL_DOWN)) + { + mCurr = n; + mObjects[mCurr]->Entering(); + } + } + } + else + mLastKey = 0; } diff --git a/projects/mtg/src/Logger.cpp b/projects/mtg/src/Logger.cpp index c2d8c5963..3766fe3ad 100644 --- a/projects/mtg/src/Logger.cpp +++ b/projects/mtg/src/Logger.cpp @@ -1,23 +1,23 @@ -#include "../include/debug.h" -#include "../include/Logger.h" -#include -#include -using namespace std; - -#if defined (WIN32) - #include -#endif - -void Logger::Log(char * text){ - ofstream file (LOG_FILE,ios_base::app); - if (file){ - file << text; - file << "\n"; - file.close(); - } -#if defined (WIN32) || defined (LINUX) - OutputDebugString(text); - OutputDebugString("\n"); -#endif - -} +#include "../include/debug.h" +#include "../include/Logger.h" +#include +#include +using namespace std; + +#if defined (WIN32) +#include +#endif + +void Logger::Log(char * text){ + ofstream file (LOG_FILE,ios_base::app); + if (file){ + file << text; + file << "\n"; + file.close(); + } +#if defined (WIN32) || defined (LINUX) + OutputDebugString(text); + OutputDebugString("\n"); +#endif + +} diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 5c72ab516..dfcebb80b 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -1,1723 +1,1723 @@ -#include "../include/debug.h" -#include "../include/MTGAbility.h" -#include "../include/ManaCost.h" -#include "../include/MTGGameZones.h" -#include "../include/AllAbilities.h" -#include "../include/Damage.h" -#include "../include/TargetChooser.h" -#include "../include/CardGui.h" -#include "../include/MTGDeck.h" - -int AbilityFactory::destroyAllFromTypeInPlay(const char * type, MTGCardInstance * source, int bury){ - GameObserver * game = GameObserver::GetInstance(); - for (int i = 0; i < 2 ; i++){ - for (int j = 0; j < game->players[i]->game->inPlay->nb_cards; j++){ - MTGCardInstance * current = game->players[i]->game->inPlay->cards[j]; - if (current->hasType(type)){ - if (bury){ - game->players[i]->game->putInGraveyard(current); - }else{ - game->mLayers->stackLayer()->addPutInGraveyard(current); - } - } - } - } - return 1; -} - -int AbilityFactory::destroyAllFromColorInPlay(int color, MTGCardInstance * source, int bury){ - GameObserver * game = GameObserver::GetInstance(); - for (int i = 0; i < 2 ; i++){ - for (int j = 0; j < game->players[i]->game->inPlay->nb_cards; j++){ - MTGCardInstance * current = game->players[i]->game->inPlay->cards[j]; - if (current->hasColor(color)){ - if (bury){ - game->players[i]->game->putInGraveyard(current); - }else{ - game->mLayers->stackLayer()->addPutInGraveyard(current); - } - } - } - } - return 1; -} - -int AbilityFactory::putInPlayFromZone(MTGCardInstance * card, MTGGameZone * zone, Player * p){ - Spell * spell = NEW Spell(card); - p->game->putInZone(card, zone, p->game->stack); - spell->resolve(); - delete spell; - return 1; -} - -//Some basic functionnalities that can be added automatically in the text file -int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){ - int dryMode = 0; - if (!spell) dryMode = 1; - GameObserver * game = GameObserver::GetInstance(); - if (!card) card = spell->source; - MTGCardInstance * target = card->target; - if (!target) target = card; - string magicText = card->magicText; - if (card->alias && magicText.size() == 0){ - //An awful way to gat access to the aliasedcard - magicText = GameObserver::GetInstance()->players[0]->game->collection->getCardById(card->alias)->magicText; - } - string s; - int size = magicText.size(); - if (size == 0) return 0; - unsigned int found; - int result = id; - - - while (magicText.size()){ - found = magicText.find("\n"); - if (found != string::npos){ - s = magicText.substr(0,found); - magicText = magicText.substr(found+1); - }else{ - s = magicText; - magicText = ""; - } -#if defined (WIN32) || defined (LINUX) - char buf[4096]; - sprintf(buf, "AUTO ACTION: %s\n", s.c_str()); - OutputDebugString(buf); -#endif - - TargetChooser * tc = NULL; - int doTap = 0; - string lordType = ""; - - //Tap in the cost ? - if (s.find("{t}") != string::npos) doTap = 1; - - //Target Abilities - found = s.find("target("); - if (found != string::npos){ - int end = s.find(")"); - string target = s.substr(found + 7,end - found - 7); - TargetChooserFactory tcf; - tc = tcf.createTargetChooser(target, card); - - } - - //Lord - found = s.find("lord("); - if (found != string::npos){ - if (dryMode) return BAKA_EFFECT_GOOD; - unsigned int end = s.find(")", found+5); - if (end != string::npos){ - lordType = s.substr(found+5,end-found-5).c_str(); - } - } - - //Champion. Very basic, needs to be improved ! - found = s.find("champion(name:"); - if (found != string::npos){ - if (dryMode) return BAKA_EFFECT_GOOD; - unsigned int end = s.find(")", found+14); - if (end != string::npos){ - string type = s.substr(found+14,end-found-14).c_str(); - game->addObserver(NEW APlagueRats(id,card,type.c_str())); - result++; - continue; - } - } - - //Untapper (Ley Druid...) - found = s.find("untap"); - if (found != string::npos){ - if (dryMode) return BAKA_EFFECT_GOOD; - ManaCost * cost = ManaCost::parseManaCost(s); - if (tc){ - game->addObserver(NEW AUntaper(id, card, cost, tc)); - }else{ - target->tapped = 0; - } - - result++; - continue; - } - - //Tapper (icy manipulator) - found = s.find("tap"); - if (found != string::npos){ - if (dryMode) return BAKA_EFFECT_GOOD; - ManaCost * cost = ManaCost::parseManaCost(s); - if (tc){ - game->addObserver(NEW ATapper(id, card, cost, tc)); - }else{ - target->tapped = 1; - } - - result++; - continue; - } - //Tentative Destroyall not working char is not compatible with string variable - //found = s.find("destroyall("); - //if (found != string::npos){ - // if (dryMode) return BAKA_EFFECT_GOOD; - // unsigned int end = s.find(")", found+11); - // if (end != string::npos){ - // string type = s.substr(found+11,end-found-11).c_str(); - // destroyAllFromTypeInPlay(type.c_str(), card); - // result++; - // continue; - //} - - //Regeneration - found = s.find("}:regenerate"); - if (found != string::npos){ - if (dryMode) return BAKA_EFFECT_GOOD; - ManaCost * cost = ManaCost::parseManaCost(s); - - if (lordType.size() > 0){ - game->addObserver(NEW ALord(id,card,lordType.c_str(),0,0,-1,cost)); - }else{ - - if (tc){ - //TODO - }else{ - game->addObserver(NEW AStandardRegenerate(id, card, target, cost)); - //TODO death ward ! - } - } - result++; - continue; - } - //Bury - found = s.find("bury"); - if (found != string::npos){ - if (dryMode) return BAKA_EFFECT_BAD; - if (tc){ - game->addObserver(NEW ABurier(id, card,tc)); - }else{ - target->controller()->game->putInGraveyard(target); - } - result++; - continue; - } - //Destroy - found = s.find("destroy"); - if (found != string::npos){ - if (dryMode) return BAKA_EFFECT_BAD; - if (tc){ - game->addObserver(NEW ADestroyer(id, card,tc)); - }else{ - game->mLayers->stackLayer()->addPutInGraveyard(target); - } - result++; - continue; - } - - //Summon - - //Reveal Take Target and put in in hand (should be also able to target hand since some card needs you to reveal a card in your hand - - //Damage - found = s.find("damage"); - if (found != string::npos){ - unsigned int start = s.find(":",found); - unsigned int end = s.find(" ",start); - int damage; - ManaCost * cost = ManaCost::parseManaCost(s); - if (end != string::npos){ - damage = atoi(s.substr(start+1,end-start-1).c_str()); - }else{ - damage = atoi(s.substr(start+1).c_str()); - } - if (dryMode) return BAKA_EFFECT_BAD; - if (tc){ - game->addObserver(NEW ADamager(id, card, cost, damage, tc,doTap)); - }else{ - delete cost; - game->mLayers->stackLayer()->addDamage(card,spell->getNextDamageableTarget(), damage); - } - result++; - continue; - } - - //gain/lose life - found = s.find("life"); - if (found != string::npos){ - unsigned int start = s.find(":",found); - unsigned int end = s.find(" ",start); - int life; - ManaCost * cost = ManaCost::parseManaCost(s); - if (end != string::npos){ - life = atoi(s.substr(start+1,end-start-1).c_str()); - }else{ - life = atoi(s.substr(start+1).c_str()); - } - if (dryMode) return BAKA_EFFECT_GOOD; - if (tc){ - //TODO ? - }else{ - if (cost->getConvertedCost() == 0 && !doTap){ - delete cost; - card->controller()->life+=life; - }else{ - //TODO; - } - } - result++; - continue; - } - - //Draw - found = s.find("draw"); - if (found != string::npos){ - unsigned int start = s.find(":",found); - unsigned int end = s.find(" ",start); - int nbcards; - ManaCost * cost = ManaCost::parseManaCost(s); - if (end != string::npos){ - nbcards = atoi(s.substr(start+1,end-start-1).c_str()); - }else{ - nbcards = atoi(s.substr(start+1).c_str()); - } - if (dryMode) return BAKA_EFFECT_GOOD; - if (tc){ - //TODO ? - }else{ - if (cost->getConvertedCost() == 0){ - delete cost; - game->mLayers->stackLayer()->addDraw(card->controller(),nbcards); - }else{ - game->addObserver(NEW ADrawer(id,card,cost,nbcards,doTap)); - } - } - result++; - continue; - } - - //Change Power/Toughness - found = s.find("/"); - if (found != string::npos){ - unsigned int start = s.find(":"); - if (start == string::npos) start = -1; - int power = atoi(s.substr(start+1,size-found).c_str()); - unsigned int end = s.find(" ",start); - int toughness; - if (end != string::npos){ - toughness = atoi(s.substr(found+1,end-found-1).c_str()); - }else{ - toughness = atoi(s.substr(found+1).c_str()); - } - if (dryMode){ - if (power >=0 && toughness >= 0 ) return BAKA_EFFECT_GOOD; - return BAKA_EFFECT_BAD; - } - int limit = 0; - unsigned int limit_str = s.find("limit:"); - if (limit_str != string::npos){ - limit = atoi(s.substr(limit_str+6).c_str()); - } - ManaCost * cost = ManaCost::parseManaCost(s); - - if (lordType.size() > 0){ - game->addObserver(NEW ALord(id,card,lordType.c_str(),power,toughness)); - }else{ - if(tc){ - game->addObserver(NEW ATargetterPowerToughnessModifierUntilEOT(id, card,power,toughness, cost, tc)); - }else{ - if (cost->getConvertedCost() == 0){ - delete cost; - if(card->hasType("enchantment")){ - game->addObserver(NEW APowerToughnessModifier(id, card, target,power,toughness)); - }else{ - game->addObserver(NEW AInstantPowerToughnessModifierUntilEOT(id, card, target,power,toughness)); - } - }else{ - game->addObserver(NEW APowerToughnessModifierUntilEndOfTurn(id, card, target,power,toughness, cost, limit)); - } - } - } - result++; - continue; - } - - //Mana Producer - found = s.find("add"); - if (found != string::npos){ - if (dryMode) return BAKA_EFFECT_GOOD; - ManaCost * cost = ManaCost::parseManaCost(s.substr(0,found)); - ManaCost * output = ManaCost::parseManaCost(s.substr(found)); - if (cost->getConvertedCost()){ - game->addObserver(NEW AManaProducer(id, target, output, cost)); - }else{ - delete cost; - if (doTap){ - game->addObserver(NEW AManaProducer(id, target, output)); - }else{ - card->controller()->getManaPool()->add(output); - delete output; - } - - } - result++; - continue; - } - - //Gain/loose Ability - for (int j = 0; j < NB_BASIC_ABILITIES; j++){ - found = s.find(MTGBasicAbilities[j]); - if (found!= string::npos){ - int modifier = 1; - if (found > 0 && s[found-1] == '-') modifier = 0; - if (dryMode){ - if (j == DEFENDER){ - if (modifier == 1) return BAKA_EFFECT_BAD; - return BAKA_EFFECT_GOOD; - }else{ - if (modifier == 1) return BAKA_EFFECT_GOOD; - return BAKA_EFFECT_BAD; - } - } - ManaCost * cost = ManaCost::parseManaCost(s); - - if (lordType.size() > 0){ - game->addObserver(NEW ALord(id,card,lordType.c_str(),0,0,j)); - }else{ - - if (tc){ - game->addObserver(NEW ABasicAbilityModifierUntilEOT(id, card, j, cost,tc, modifier)); - }else{ - if (cost->getConvertedCost() == 0){ - delete cost; - if(card->hasType("enchantment")){ - game->addObserver(NEW ABasicAbilityModifier(id, card,target, j,modifier)); - }else{ - game->addObserver(NEW AInstantBasicAbilityModifierUntilEOT(id, card,target, j,modifier)); - } - }else{ - game->addObserver(NEW ABasicAbilityAuraModifierUntilEOT(id, card,target, cost,j,modifier)); - } - } - } - result++; - continue; - } - } - } - return result; - - -} - -void AbilityFactory::addAbilities(int _id, Spell * spell){ - MTGCardInstance * card = spell->source; - if (spell->cursor==1) card->target = spell->getNextCardTarget(); - _id = magicText(_id, spell); - int putSourceInGraveyard = 0; //For spells that are not already InstantAbilities; - - - GameObserver * game = GameObserver::GetInstance(); - int id = card->model->getId(); - if (card->alias) id = card->alias; - switch (id){ - case 1092: //Aladdin's lamp - { - AAladdinsLamp * ability = NEW AAladdinsLamp(_id, card); - game->addObserver(ability); - break; - } - case 130550: //Ancestor's chosen - { - int life = card->controller()->game->graveyard->nb_cards; - card->controller()->life+= life; - break; - } - case 1190: //Animate Artifact - { - int x = card->target->getManaCost()->getConvertedCost(); - game->addObserver(NEW AConvertToCreatureAura(_id, card,card->target,x,x)); - break; - } - case 1094: //Ank Of Mishra - { - AAnkhOfMishra * ability = NEW AAnkhOfMishra(_id,card); - game->addObserver(ability); - break; - } - case 1095: //Armageddon clock - { - AArmageddonClock * ability = NEW AArmageddonClock(_id,card); - game->addObserver(ability); - break; - } - case 106525: //Ascendant Evincar - { - game->addObserver(NEW AColorLord(_id, card,MTG_COLOR_BLACK,-1,1,1)); - game->addObserver(NEW AColorLord(_id, card,0,MTG_COLOR_BLACK,-1,-1)); - break; - } - - case 1096: //Basalt Monolith - { - int cost[] = {MTG_COLOR_ARTIFACT, 3}; - AManaProducer * ability = NEW AManaProducer(_id, card, NEW ManaCost(cost,1)); - AUntapManaBlocker * ability2 = NEW AUntapManaBlocker(_id+1, card, NEW ManaCost(cost,1)); - AUnBlocker * ability3 = NEW AUnBlocker(_id+1, card,card, NEW ManaCost(cost,1)); - - game->addObserver(ability); - game->addObserver(ability2); - game->addObserver(ability3); - break; - } - case 1097: //Black Vise - { - game->addObserver( NEW ALifeZoneLink(_id ,card, MTG_PHASE_UPKEEP, 4)); - break; - } - case 1191: //Blue Elemental Blast - { - if (card->target){ - card->target->controller()->game->putInGraveyard(card->target); - }else{ - Spell * starget = spell->getNextSpellTarget(); - game->mLayers->stackLayer()->Fizzle(starget); - } - break; - } - case 1099: //Brass Man - { - int cost[] = {MTG_COLOR_ARTIFACT, 1}; - game->addObserver(NEW AUntapManaBlocker(_id, card, NEW ManaCost(cost,1))); - break; - } - case 1237: //Channel - { - game->addObserver(NEW AChannel(_id, card)); - break; - } - case 1282: //Chaoslace - { - if (card->target){ - card->target->setColor(MTG_COLOR_RED, 1); - }else{ - Spell * starget = spell->getNextSpellTarget(); - starget->source->setColor(MTG_COLOR_RED, 1); - } - break; - } - case 1335: //Circle of protection : black - { - game->addObserver(NEW ACircleOfProtection( _id,card, MTG_COLOR_BLACK)); - break; - } - case 1336: //Circle of protection : blue - { - game->addObserver(NEW ACircleOfProtection( _id,card, MTG_COLOR_BLUE)); - break; - } - case 1337: //Circle of protection : green - { - game->addObserver(NEW ACircleOfProtection( _id,card, MTG_COLOR_GREEN)); - break; - } - case 1338: //Circle of protection : red - { - game->addObserver(NEW ACircleOfProtection( _id,card, MTG_COLOR_RED)); - break; - } - case 1339: //Circle of protection : white - { - game->addObserver(NEW ACircleOfProtection( _id,card, MTG_COLOR_WHITE)); - break; - } - case 1101: //clockwork Beast - { - game->addObserver(NEW AClockworkBeast(_id,card)); - break; - } - case 1102: //Conservator - { - game->addObserver(NEW AConservator(_id,card)); - break; - } - case 1196: //Counterspell - { - Spell * starget = spell->getNextSpellTarget(); - if (starget) game->mLayers->stackLayer()->Fizzle(starget); - break; - } - case 1197: //Creature Bond - { - game->addObserver(NEW ACreatureBond(_id,card, card->target)); - break; - } - case 1103: //Crystal Rod - { - int cost[] = {MTG_COLOR_BLUE, 1}; - ASpellCastLife* ability = NEW ASpellCastLife(_id, card, MTG_COLOR_WHITE,NEW ManaCost(cost,1) , 1); - game->addObserver(ability); - break; - } - case 1151: //Deathgrip - { - int _cost[] = {MTG_COLOR_BLACK, 2}; - game->addObserver(NEW ASpellCounterEnchantment(_id, card, NEW ManaCost(_cost, 1),MTG_COLOR_GREEN)); - break; - } - case 1152: //Deathlace - { - if (card->target){ - card->target->setColor(MTG_COLOR_BLACK, 1); - }else{ - Spell * starget = spell->getNextSpellTarget(); - starget->source->setColor(MTG_COLOR_BLACK, 1); - } - break; - } - case 1105: //dingus Egg - { - ADingusEgg * ability = NEW ADingusEgg(_id,card); - game->addObserver(ability); - break; - } - case 1106: //Disrupting Scepter - { - ADisruptingScepter * ability = NEW ADisruptingScepter(_id,card); - game->addObserver(ability); - break; - } - case 1284: //Dragon Whelp - { - game->addObserver(NEW ADragonWhelp(_id,card)); - break; - } - case 1108: //Ebony Horse - { - AEbonyHorse * ability = NEW AEbonyHorse(_id,card); - game->addObserver(ability); - break; - } - case 1345: //Farmstead - { - game->addObserver(NEW AFarmstead(_id, card,card->target)); - break; - } - case 1291: //Fireball - { - int x = spell->cost->getConvertedCost() - 1; //TODO BETTER - game->addObserver(NEW AFireball(_id, card,spell, x)); - break; - } - case 1245: //Force of Nature - { - game->addObserver(NEW AForceOfNature(_id,card)); - break; - } - case 1110: //Glasses Of Urza - { - AGlassesOfUrza * ability = NEW AGlassesOfUrza(_id,card); - game->addObserver(ability); - break; - } - case 1112: //Howling Mine - { - game->addObserver(NEW AHowlingMine(_id, card)); - break; - } - case 1252: //Instill Energy - { - game->addObserver(NEW AUntaperOnceDuringTurn(_id, card, card->target, NEW ManaCost())); - break; - } - case 1113: //Iron Star - { - int cost[] = {MTG_COLOR_ARTIFACT, 1}; - ASpellCastLife* ability = NEW ASpellCastLife(_id, card, MTG_COLOR_RED,NEW ManaCost(cost,1) , 1); - game->addObserver(ability); - break; - } - case 1351: // Island Sancturay - { - game->addObserver(NEW AIslandSanctuary(_id, card)); - break; - } - case 1114: //Ivory cup - { - int cost[] = {MTG_COLOR_ARTIFACT, 1}; - ASpellCastLife* ability = NEW ASpellCastLife(_id, card, MTG_COLOR_WHITE,NEW ManaCost(cost,1) , 1); - game->addObserver(ability); - break; - } - case 1115: //Ivory Tower - { - game->addObserver(NEW ALifeZoneLink(_id ,card, MTG_PHASE_UPKEEP, 4, 1, 1)); - break; - } - case 1117: //Jandors Ring - { - game->addObserver(NEW AJandorsRing( _id, card)); - break; - } - case 1121: //Kormus Bell - { - game->addObserver(NEW AConvertLandToCreatures(id, card, "swamp")); - break; - } - case 1254: //Kudzu - { - game->addObserver(NEW AKudzu(id, card, card->target)); - break; - } - case 1256: //LifeForce - { - int _cost[] = {MTG_COLOR_GREEN, 2}; - game->addObserver(NEW ASpellCounterEnchantment(_id, card, NEW ManaCost(_cost, 1),MTG_COLOR_BLACK)); - break; - } - case 1257: //Lifelace - { - if (card->target){ - card->target->setColor(MTG_COLOR_GREEN, 1); - }else{ - Spell * starget = spell->getNextSpellTarget(); - starget->source->setColor(MTG_COLOR_GREEN, 1); - } - break; - } - case 1205: //Lifetap - { - game->addObserver(NEW AGiveLifeForTappedType(_id, card, "forest")); - break; - } - case 1259: //Living lands - { - game->addObserver(NEW AConvertLandToCreatures(id, card, "forest")); - break; - } - case 1124: //Mana Vault - { - int output[] = {MTG_COLOR_ARTIFACT, 3}; - game->addObserver(NEW AManaProducer(_id,card,NEW ManaCost(output,1))); - int cost[] = {MTG_COLOR_ARTIFACT, 4}; - game->addObserver(NEW AUntapManaBlocker(_id+1, card, NEW ManaCost(cost,1))); - game->addObserver(NEW ARegularLifeModifierAura(_id+2, card, card, MTG_PHASE_DRAW, -1, 1)); - break; - } - case 1126:// Millstone - { - game->addObserver( NEW AMillstone(_id ,card)); - break; - } - case 1215: //Power Leak - { - game->addObserver( NEW APowerLeak(_id ,card, card->target)); - break; - } - case 1311: //Power Surge - { - game->addObserver( NEW APowerSurge(_id ,card)); - break; - } - case 1358: //Purelace - { - if (card->target){ - card->target->setColor(MTG_COLOR_WHITE, 1); - }else{ - Spell * starget = spell->getNextSpellTarget(); - starget->source->setColor(MTG_COLOR_WHITE, 1); - } - break; - } - case 1312: //Red Elemental Blast - { - if (card->target){ - card->target->controller()->game->putInGraveyard(card->target); - }else{ - Spell * starget = spell->getNextSpellTarget(); - game->mLayers->stackLayer()->Fizzle(starget); - } - break; - } - case 1136: //Soul Net - { - game->addObserver( NEW ASoulNet(_id ,card)); - break; - } - case 1139: //The Rack - { - game->addObserver( NEW ALifeZoneLink(_id ,card, MTG_PHASE_UPKEEP, -3)); - break; - } - case 1140: //Throne of bones - { - int cost[] = {MTG_COLOR_ARTIFACT, 1}; - ASpellCastLife* ability = NEW ASpellCastLife(_id, card, MTG_COLOR_BLACK,NEW ManaCost(cost,1) , 1); - game->addObserver(ability); - break; - } - case 1142: //Wooden Sphere - { - int cost[] = {MTG_COLOR_ARTIFACT, 1}; - ASpellCastLife* ability = NEW ASpellCastLife(_id, card, MTG_COLOR_GREEN,NEW ManaCost(cost,1) , 1); - game->addObserver(ability); - break; - } - case 1143: //Animate Dead - { - game->addObserver(NEW AAnimateDead(_id, card, card->target)); - break; - } - case 1144: //Bad moon - { - game->addObserver(NEW ABadMoon(_id,card)); - break; - } - case 1148 : //Cursed lands - { - game->addObserver(NEW AWanderlust(_id, card, card->target)); - break; - } - case 1156: //Drain Life - { - Damageable * target = spell->getNextDamageableTarget(); - int x = spell->cost->getConvertedCost() - 2; //TODO Fix that !!! + X should be only black mana, that needs to be checked ! - game->mLayers->stackLayer()->addDamage(card, target, x); - if (target->life < x) x = target->life; - game->currentlyActing()->life+=x; - break; - } - case 1159: //Erg Raiders - { - AErgRaiders* ability = NEW AErgRaiders(_id, card); - game->addObserver(ability); - break; - } - case 1164: //Howl from beyond - { - int x = spell->cost->getConvertedCost() - 1; //TODO, this is not enough, Spells shouls have a function like "xCost" because the spell might cost more than expected to launch - AInstantPowerToughnessModifierUntilEOT * ability = NEW AInstantPowerToughnessModifierUntilEOT( _id, card, card->target, x, 0); - game->addObserver(ability); - break; - } - case 1202: //Hurkyl's Recall - { - Player * player = spell->getNextPlayerTarget(); - if (player){ - for (int i = 0; i < 2; i++){ - MTGInPlay * inplay = game->players[i]->game->inPlay; - for (int j= inplay->nb_cards -1 ; j >=0 ; j--){ - MTGCardInstance * card = inplay->cards[j]; - if (card->owner == player && card->hasType("artifact")){ - player->game->putInZone(card, inplay, player->game->hand); - } - } - } - } - break; - } - case 1165: //Hypnotic Specter - { - game->addObserver(NEW AHypnoticSpecter( _id, card)); - break; - } - case 1258: //Living Artifact - { - game->addObserver(NEW ALivingArtifact( _id, card, card->target)); - break; - } - case 1166: //Lord Of The Pit - { - game->addObserver(NEW ALordOfThePit( _id, card)); - break; - } - case 1209: //Mana Short - { - Player * player = spell->getNextPlayerTarget(); - if (player){ - MTGInPlay * inplay = player->game->inPlay; - for (int i = 0; i < inplay->nb_cards; i++){ - MTGCardInstance * current = inplay->cards[i]; - if (current->hasType("land")) current->tapped = 1; - } - player->getManaPool()->init(); - } - break; - } - case 1167: //Mind Twist - { - int xCost = spell->cost->getConvertedCost() - 1; - for (int i = 0; i < xCost; i++){ - game->opponent()->game->discardRandom(game->opponent()->game->hand); - } - break; - } - case 1170: //Nightmare - { - game->addObserver(NEW ANightmare(_id, card)); - break; - } - case 1171: //Paralysis - { - int cost[] = {MTG_COLOR_ARTIFACT, 4}; - game->addObserver(NEW AUntapManaBlocker(_id, card,card->target, NEW ManaCost(cost,1))); - card->target->tapped = 1; - break; - } - case 1172: //Pestilence - { - game->addObserver(NEW APestilence(_id, card)); - break; - } - /*case 1173: //Plague Rats - { - game->addObserver(NEW APlagueRats(_id, card, "Plague Rats")); - break; - } - */ - case 1174: //Raise Dead - { - MTGPlayerCards * zones = game->currentlyActing()->game; - zones->putInZone(card->target,zones->graveyard,zones->hand); - } - case 1176: //Sacrifice - { - ASacrifice * ability = NEW ASacrifice(_id, card, card->target); - game->addObserver(ability); - break; - } - case 1224: //Spell Blast - { - int x = spell->cost->getConvertedCost() - 1; - Spell * starget = spell->getNextSpellTarget(); - if (starget){ - if (starget->cost->getConvertedCost() <= x) game->mLayers->stackLayer()->Fizzle(starget); - } - break; - } - case 1185: //Warp Artifact - { - game->addObserver(NEW ARegularLifeModifierAura(_id, card, card->target, MTG_PHASE_UPKEEP, -1)); - break; - } - case 1192: //BrainGeyser - { - Player * player = ((Player * )spell->targets[0]); - int x = spell->cost->getConvertedCost() - 2; - for (int i = 0; i < x ; i++){ - player->game->drawFromLibrary(); - } - break; - } - case 1194: //Control Magic - { - game->addObserver(NEW ATakeControlAura(_id, card, card->target)); - break; - } - - case 1200 : //Feedback - { - game->addObserver(NEW AWanderlust(_id, card, card->target)); - break; - } - case 129601: //Icy Manipulator - { - int cost[] = {MTG_COLOR_ARTIFACT, 1}; - TypeTargetChooser * tc = new TypeTargetChooser("artifact",card); - tc->addType("land"); - tc->addType("creature"); - game->addObserver(NEW ATapper(_id,card,NEW ManaCost(cost, 1),tc)); - break; - } - - case 1203: //Island Fish - { - int cost[] = {MTG_COLOR_BLUE, 3}; - game->addObserver(NEW AUntapManaBlocker(_id, card, NEW ManaCost(cost,1))); - game->addObserver(NEW AStrongLandLinkCreature(_id, card, "island")); - break; - } - case 1214: //Pirate Ship - { - game->addObserver(NEW AStrongLandLinkCreature(_id, card, "island")); - game->addObserver(NEW ADamager(_id+1, card, NEW ManaCost(), 1)); - break; - } - case 1218: //Psychic Venom - { - game->addObserver(NEW APsychicVenom(_id, card, card->target)); - break; - } - case 1220: //Sea Serpent - { - game->addObserver(NEW AStrongLandLinkCreature(_id, card, "island")); - break; - } - case 1315: //Sedge Troll - { - game->addObserver( NEW ASedgeTroll(_id, card)); - break; - } - case 1221: //Serendib Efreet - { - game->addObserver( NEW ASerendibEfreet(_id, card)); - break; - } - case 1226: //Steal Artifact - { - game->addObserver( NEW AControlStealAura(_id, card, card->target)); - break; - } - case 1228: //Unstable mutation - { - game->addObserver(NEW APowerToughnessModifier(_id, card, card->target, 3, 3)); - game->addObserver(NEW APowerToughnessModifierRegularCounter(_id, card, card->target, MTG_PHASE_UPKEEP, -1, -1)); - break; - } - case 1229: //Unsummon - { - MTGPlayerCards * zones = card->target->controller()->game; - zones->putInZone(card->target,zones->inPlay,zones->hand); - break; - } - case 1235: //Aspect of Wolf - { - game->addObserver(NEW AAspectOfWolf(_id, card, card->target)); - break; - } - case 1236: //Birds of Paradise - { - for (int i = MTG_COLOR_GREEN; i <= MTG_COLOR_WHITE; i++){ - int output[]={i,1}; - game->addObserver(NEW AManaProducer(_id + i, card, NEW ManaCost(output,1))); - } - break; - } - case 1240: //Crumble - { - card->target->controller()->game->putInGraveyard(card->target); - card->target->controller()->life+= card->target->getManaCost()->getConvertedCost(); - break; - } - case 1251: //Hurricane - { - int x = spell->cost->getConvertedCost() - 1; - for (int i = 0; i < 2 ; i++){ - game->mLayers->stackLayer()->addDamage(card, game->players[i], x); - for (int j = 0; j < game->players[i]->game->inPlay->nb_cards; j++){ - MTGCardInstance * current = game->players[i]->game->inPlay->cards[j]; - if (current->basicAbilities[FLYING] && current->isACreature()){ - game->mLayers->stackLayer()->addDamage(card, current, x); - } - } - } - break; - } - case 1262: //Regeneration - { - int cost[] = {MTG_COLOR_GREEN, 1}; - game->addObserver(NEW AStandardRegenerate(_id,card,card->target,NEW ManaCost(cost,1))); - break; - } - case 1263: //Regrowth - { - MTGPlayerCards * zones = game->currentlyActing()->game; - zones->putInZone(card->target,zones->graveyard,zones->hand); - break; - } - case 1266: //stream of life - { - int x = spell->cost->getConvertedCost() - 1; //TODO Improve that ! - spell->getNextPlayerTarget()->life += x; - break; - } - case 1270: //tranquility - { - destroyAllFromTypeInPlay("enchantment", card); - break; - } - case 1271: //Tsunami - { - destroyAllFromTypeInPlay("island", card); - break; - } - case 1231: //Volcanic Eruption - { - int x = spell->cost->getConvertedCost() - 3; - int _x = x; - MTGCardInstance * target = spell->getNextCardTarget(); - while(target && _x){ - game->mLayers->stackLayer()->addPutInGraveyard(target); - _x--; - target = spell->getNextCardTarget(target); - } - x-=_x; - for (int i = 0; i < 2 ; i++){ - game->mLayers->stackLayer()->addDamage(card, game->players[i], x); - for (int j = 0; j < game->players[i]->game->inPlay->nb_cards; j++){ - MTGCardInstance * current = game->players[i]->game->inPlay->cards[j]; - if (current->isACreature()){ - game->mLayers->stackLayer()->addDamage(card, current, x); - } - } - } - break; - } - case 1278: //Web - { - game->addObserver(NEW APowerToughnessModifier(_id, card, card->target, 0,2)); - game->addObserver(NEW ABasicAbilityModifier(_id + 1, card, card->target, REACH)); - break; - } - case 1280: //Atog - { - game->addObserver(NEW AAtog(_id, card)); - break; - } - case 1285: //Dwarven Warriors{ - { - CreatureTargetChooser * tc = NEW CreatureTargetChooser(card); - tc->maxpower = 2; - game->addObserver(NEW ABasicAbilityModifierUntilEOT(_id, card, UNBLOCKABLE, NULL,tc)); - break; - } - case 1288: //EarthBind - { - game->addObserver(NEW AEarthbind(_id, card, card->target)); - break; - } - case 1289: //earthquake - { - int x = spell->cost->getConvertedCost() - 1; - for (int i = 0; i < 2 ; i++){ - game->mLayers->stackLayer()->addDamage(card, game->players[i], x); - for (int j = 0; j < game->players[i]->game->inPlay->nb_cards; j++){ - MTGCardInstance * current = game->players[i]->game->inPlay->cards[j]; - if (!current->basicAbilities[FLYING] && current->isACreature()){ - game->mLayers->stackLayer()->addDamage(card, current, x); - } - } - } - break; - } - case 1344: //Eye for an Eye - { - Damage * damage = spell->getNextDamageTarget(); - if (damage){ - game->mLayers->stackLayer()->addDamage(card,damage->source->controller(),damage->damage); - } - break; - } - case 1243: //Fastbond - { - game->addObserver(NEW AFastbond(_id, card)); - break; - } - case 1293: //FlashFires - { - destroyAllFromTypeInPlay("plains", card); - break; - } - case 1301: // Keldon Warlord - { - game->addObserver(NEW AKeldonWarlord(_id, card)); - break; - } - case 1302: //Kird Ape - { - game->addObserver(NEW AKirdApe(_id, card)); - break; - } - case 1309: //Orcish Artillery - { - game->addObserver(NEW AOrcishArtillery(_id, card)); - break; - } - case 1310: //Orcish Oriflame - { - game->addObserver(NEW AOrcishOriflame(_id, card)); - break; - } - case 1317: //ShatterStorm - { - destroyAllFromTypeInPlay("artifact", card, 1); - break; - } - case 1326: //Wheel of fortune - { - for (int i = 0; i < 2; i++){ - MTGLibrary * library = game->players[i]->game->library; - MTGHand * hand = game->players[i]->game->hand; - for (int j = hand->nb_cards-1; j>=0; j--){ - game->players[i]->game->putInGraveyard(hand->cards[j]); - } - for(int j = 0; j < 7; j++){ - game->players[i]->game->drawFromLibrary(); - } - } - break; - } - case 1328: //Armageddon - { - destroyAllFromTypeInPlay("land", card); - break; - } - case 1331: //Black Ward - { - game->addObserver(NEW AProtectionFrom( _id,card, card->target, MTG_COLOR_BLACK)); - break; - } - case 1333: //Blue Ward - { - game->addObserver(NEW AProtectionFrom( _id,card, card->target, MTG_COLOR_BLUE)); - break; - } - case 1334: //Castle - { - game->addObserver(NEW ACastle(_id,card)); - break; - } - case 1238: //Cockatrice - { - game->addObserver(NEW AOldSchoolDeathtouch(_id,card)); - break; - } - case 1341: //Crusade: - { - game->addObserver(NEW ABadMoon(_id,card, MTG_COLOR_WHITE)); - break; - - } - case 1346: //Green Ward - { - game->addObserver(NEW AProtectionFrom( _id,card, card->target, MTG_COLOR_GREEN)); - break; - } - case 1352: //Karma - { - game->addObserver(NEW AKarma(_id, card)); - break; - } - case 1355: //Northern Paladin - { - game->addObserver(NEW ANorthernPaladin(_id, card)); - break; - } - case 1359: //Red Ward - { - game->addObserver(NEW AProtectionFrom( _id,card, card->target, MTG_COLOR_RED)); - break; - } - case 1360: //Resurrection - { - Player * p = card->controller(); - AbilityFactory af; - af.putInPlayFromZone(card->target, p->game->graveyard, p); - break; - } - case 1362: //Reverse polarity - { - ActionStack * as = game->mLayers->stackLayer(); - Player * controller = card->controller(); - Damage * current = ((Damage *)as->getNext(NULL,ACTION_SPELL, RESOLVED_OK)); - while(current){ - if (current->target == controller && current->source->hasType("artifact")){ - controller->life+= current->damage * 2; - } - current = ((Damage *)as->getNext(current,ACTION_SPELL, RESOLVED_OK)); - } - break; - } - case 1225: //Stasis - { - game->addObserver(NEW AStasis(_id, card)); - break; - } - - case 1367: //Sword to Plowshares - { - card->target->controller()->life+= card->target->power; - card->target->controller()->game->inPlay->removeCard(card->target); - break; - } - case 1182: //Terror - { - if (card->target->hasColor(MTG_COLOR_BLACK) || card->target->hasSubtype("artifact")){ - }else{ - card->target->controller()->game->putInGraveyard(card->target); - } - break; - } - case 1267: //Thicket Basilic - { - game->addObserver(NEW AOldSchoolDeathtouch(_id,card)); - break; - } - case 1227: //Toughtlace - { - if (card->target){ - card->target->setColor(MTG_COLOR_BLUE, 1); - }else{ - Spell * starget = spell->getNextSpellTarget(); - starget->source->setColor(MTG_COLOR_BLUE, 1); - } - break; - } - case 1371: //White Ward - { - game->addObserver(NEW AProtectionFrom( _id,card, card->target, MTG_COLOR_WHITE)); - break; - } - case 1372: //Wrath of God - { - destroyAllFromTypeInPlay("creature", card); //TODO -> bury !!! - break; - } - - -// Addons ALA - - case 175114: // Master of Etherium - { - game->addObserver(NEW ACreaturePowerToughnessModifierForAllTypeControlled(_id,card,"artifact")); - break; - } - - case 174989: // Wild Nacatl - { - game->addObserver(NEW AGenericKirdApe(_id,card,"plains",1,1)); - game->addObserver(NEW AGenericKirdApe(_id,card,"moutain",1,1)); - break; - } - -//Addons The Dark - - case 1797: //Inferno does 6 damage to all players and all creatures. - { - for (int i = 0; i < 2 ; i++){ - game->mLayers->stackLayer()->addDamage(card, game->players[i], 6); - for (int j = 0; j < game->players[i]->game->inPlay->nb_cards; j++){ - MTGCardInstance * current = game->players[i]->game->inPlay->cards[j]; - if (current->isACreature()){ - game->mLayers->stackLayer()->addDamage(card, current, 6); - } - } - } - break; - } - - case 1773 : //People of the Woods - { - game->addObserver(NEW APeopleOfTheWoods(_id, card)); - break; - } - - case 1818: //Tivadar's Crusade - { - destroyAllFromTypeInPlay("goblin", card); - break; - } - -//Addons Legends - case 1470: //Acid Rain - { - destroyAllFromTypeInPlay("forest", card); - break; - } - case 1427: //Abomination - { - game->addObserver(NEW AAbomination(_id,card)); - break; - } - case 1533: //Livingplane - { - game->addObserver(NEW AConvertLandToCreatures(id, card, "land")); - break; - } - case 1607: //Divine Offering - { - card->target->controller()->game->putInGraveyard(card->target); - game->currentlyActing()->life+= card->target->getManaCost()->getConvertedCost(); - break; - } - case 1625: //Lifeblood - { - game->addObserver(NEW AGiveLifeForTappedType (_id, card, "island")); - break; - } -//Addons ICE-AGE Cards - case 2631: //Jokulhaups - { - destroyAllFromTypeInPlay("artifact", card); - destroyAllFromTypeInPlay("creature", card); - destroyAllFromTypeInPlay("land", card); - break; - } - - case 2650: //Pyroclasm Need to be improved copied from hurricane with does 0 dammage to player and does 2 dammage to each creature - { - int x = 2; - for (int i = 0; i < 2 ; i++){ - game->mLayers->stackLayer()->addDamage(card, game->players[i], 0);// To be removed ? - for (int j = 0; j < game->players[i]->game->inPlay->nb_cards; j++){ - MTGCardInstance * current = game->players[i]->game->inPlay->cards[j]; - if (current->isACreature()){ - game->mLayers->stackLayer()->addDamage(card, current, x); - } - } - } - break; - } - case 2660: //Word of Blasting - { - card->target->controller()->game->putInGraveyard(card->target); - card->target->controller()->life-= card->target->getManaCost()->getConvertedCost(); - break; - } - case 2443: //Dark Banishing - { - if (card->target->hasColor(MTG_COLOR_BLACK)){ - }else{ - card->target->controller()->game->putInGraveyard(card->target); - } - break; - } - case 2593: //Thoughtleech - { - game->addObserver(NEW AGiveLifeForTappedType (_id, card, "island")); - break; - } - case 2484: //Songs of the Damned - { - int mana = card->controller()->game->graveyard->countByType("creature"); - game->currentlyActing()->getManaPool()->add(MTG_COLOR_BLACK, mana); - break; - } - case 2606: //Anarchy - { - destroyAllFromColorInPlay(MTG_COLOR_WHITE, card); - break; - } - case 2474: //Minion of Leshrac - { - game->addObserver(NEW AMinionofLeshrac( _id, card)); - break; - } - case 2421: //Shield of the Age - { - game->addObserver(NEW AShieldOfTheAge( _id, card)); - break; - } - case 2487: //Spoil of Evil - { - int mana_cr = game->opponent()->game->graveyard->countByType("creature"); - int mana_ar = game->opponent()->game->graveyard->countByType("artifact"); - int spoil = mana_ar + mana_cr; - game->currentlyActing()->getManaPool()->add(MTG_COLOR_ARTIFACT, spoil); - game->currentlyActing()->life+= spoil; - break; - } - case 2435: //Whalebone Glider - { - int cost[] = {MTG_COLOR_ARTIFACT,2}; - CreatureTargetChooser * tc = NEW CreatureTargetChooser(card); - tc->maxpower = 3; - game->addObserver(NEW ABasicAbilityModifierUntilEOT(_id, card, FLYING, NEW ManaCost(cost,1),tc)); - break; - } - case 2393: //Aegis of the Meek work but work also for 0/1 creatures... :D - { - int cost[] = {MTG_COLOR_ARTIFACT,1}; - CreatureTargetChooser * tc = NEW CreatureTargetChooser(card); - tc->maxpower = 1; - tc->maxtoughness =1; - game->addObserver(NEW ATargetterPowerToughnessModifierUntilEOT(id, card, 1,2, NEW ManaCost(cost,1),tc)); - break; - } - case 2703: // Lost Order of Jarkeld - { - game->addObserver(NEW ALostOrderofJarkeld(_id, card)); - break; - } - default: - break; - } - - if (card->basicAbilities[LIFELINK]){ - ALifeLink * ability = NEW ALifeLink(_id, card); - game->addObserver(ability); - } - - for (int i=PROTECTIONGREEN; i <= PROTECTIONWHITE; i++){ - if (card->basicAbilities[i]){ - game->addObserver(NEW AProtectionFrom(_id, card, card, i - PROTECTIONGREEN + MTG_COLOR_GREEN)); - } - } - - if (card->basicAbilities[EXALTED]){ - game->addObserver(NEW AExalted(_id, card)); - } - - // Tested works the first r10 did not function because of the mistake in the array of the definition - if (card->basicAbilities[FORESTHOME]){ - game->addObserver(NEW AStrongLandLinkCreature(_id, card, "forest")); - } - if (card->basicAbilities[ISLANDHOME]){ - game->addObserver(NEW AStrongLandLinkCreature(_id, card, "island")); - } - if (card->basicAbilities[MOUNTAINHOME]){ - game->addObserver(NEW AStrongLandLinkCreature(_id, card,"moutain")); - } - if (card->basicAbilities[SWAMPHOME]){ - game->addObserver(NEW AStrongLandLinkCreature(_id, card,"swamp")); - } - if (card->basicAbilities[PLAINSHOME]){ - game->addObserver(NEW AStrongLandLinkCreature(_id, card,"plains")); - } - // New Abilities Flanking and Rampage - - if (card->basicAbilities [RAMPAGE1]){ - game->addObserver (NEW ARampageAbility(_id, card, 1, 1)); - } - - //Instants are put in the graveyard automatically if that's not already done - if (!putSourceInGraveyard){ - if (card->hasType("instant") || card->hasType("sorcery")){ - putSourceInGraveyard = 1; - } - } - if (putSourceInGraveyard == 1){ - MTGPlayerCards * zones = card->controller()->game; - zones->putInGraveyard(card); - } -} - -MTGAbility::MTGAbility(int id, MTGCardInstance * card):ActionElement(id){ - game = GameObserver::GetInstance();; - source = card; - target = card; -} - -MTGAbility::MTGAbility(int id, MTGCardInstance * _source,Damageable * _target ):ActionElement(id){ - game = GameObserver::GetInstance();; - source = _source; - target = _target; -} - -MTGAbility::~MTGAbility(){ - -} - -//returns 1 if this ability needs to be removed from the list of active abilities -int MTGAbility::testDestroy(){ - if (!game->isInPlay(source)){ - return 1; - } - if (target && !game->isInPlay((MTGCardInstance *)target)){ - source->controller()->game->putInGraveyard(source);//TODO put this in a better place ??? - return 1; - } - return 0; -} - - - -int MTGAbility::fireAbility(){ - game->mLayers->stackLayer()->addAbility(this); - return 1; -} - -// - -ActivatedAbility::ActivatedAbility(int id, MTGCardInstance * card, ManaCost * _cost, int _playerturnonly,int tap):MTGAbility(id,card), cost(_cost), playerturnonly(_playerturnonly), needsTapping(tap){ -} - - -int ActivatedAbility::isReactingToClick(MTGCardInstance * card){ - Player * player = game->currentPlayer; - if (!playerturnonly) player = game->currentlyActing(); - if (card == source && (!cost || player->getManaPool()->canAfford(cost)) && source->controller()==player && (!needsTapping || (!source->isTapped() && !source->hasSummoningSickness())) && player==game->currentlyActing()) - return 1; - return 0; -} - -int ActivatedAbility::reactToClick(MTGCardInstance * card){ - if (!isReactingToClick(card)) return 0; - if (needsTapping) source->tapped = 1; - if (cost) game->currentlyActing()->getManaPool()->pay(cost); - fireAbility(); - return 1; - -} - -int ActivatedAbility::reactToTargetClick(Targetable * object){ - if (!isReactingToTargetClick(object)) return 0; - if (needsTapping) source->tapped = 1; - if (cost) game->currentlyActing()->getManaPool()->pay(cost); - fireAbility(); - return 1; - -} - - -ActivatedAbility::~ActivatedAbility(){ - if (cost) delete cost; -} - -// - -TargetAbility::TargetAbility(int id, MTGCardInstance * card, TargetChooser * _tc,ManaCost * _cost, int _playerturnonly,int tap):ActivatedAbility(id, card,_cost,_playerturnonly, tap){ - tc = _tc; -} - -TargetAbility::TargetAbility(int id, MTGCardInstance * card,ManaCost * _cost, int _playerturnonly,int tap):ActivatedAbility(id, card,_cost,_playerturnonly, tap){ - tc = NULL; -} - -void TargetAbility::Update(float dt){ - JGE * mEngine = JGE::GetInstance(); - if (waitingForAnswer){ - if(mEngine->GetButtonClick(PSP_CTRL_CROSS)){ - waitingForAnswer = 0; - }else if(tc->targetsReadyCheck() == TARGET_OK_FULL){ - waitingForAnswer = 0; - ActivatedAbility::reactToClick(source); - } - } -} - -int TargetAbility::reactToTargetClick(Targetable * object){ - if (object->typeAsTarget() == TARGET_CARD) return reactToClick((MTGCardInstance *)object); - if (waitingForAnswer){ - tc->toggleTarget(object); - return 1; - } - return 0; -} - - -int TargetAbility::reactToClick(MTGCardInstance * card){ - if (!waitingForAnswer) { - if (isReactingToClick(card)){ - waitingForAnswer = 1; - tc->initTargets(); - } - }else{ - if (card == source){ - if (tc->targetsReadyCheck() == TARGET_OK){ - waitingForAnswer = 0; - ActivatedAbility::reactToClick(source); - } - }else{ - tc->toggleTarget(card); - } - } - return 1; -} - -void TargetAbility::Render(){ - //TODO -} - - -// - - -TriggeredAbility::TriggeredAbility(int id, MTGCardInstance * card, Damageable * _target):MTGAbility(id,card, _target){ -} - - -TriggeredAbility::TriggeredAbility(int id, MTGCardInstance * card):MTGAbility(id,card){ -} - -void TriggeredAbility::Update(float dt){ - if (trigger()) fireAbility(); -} - - - - // - InstantAbility::InstantAbility(int _id, MTGCardInstance * source):MTGAbility(_id, source){ - init = 0; - for (int i = 0; i < 2; i++){ - if(game->players[i]->game->inPlay->hasCard(source)){ - game->players[i]->game->putInGraveyard(source); - } - } - } - - void InstantAbility::Update(float dt){ - if (!init){ - init = resolve(); - } - } - - InstantAbility::InstantAbility(int _id, MTGCardInstance * source, Damageable * _target):MTGAbility(_id, source, _target){ - init = 0; - for (int i = 0; i < 2; i++){ - if(game->players[i]->game->inPlay->hasCard(source)){ - game->players[i]->game->putInGraveyard(source); - } - } - } - - - - //Instant abilities last generally until the end of the turn - int InstantAbility::testDestroy(){ - int newPhase = game->getCurrentGamePhase(); - if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP) return 1; - currentPhase = newPhase; - return 0; - - } - - - void ListMaintainerAbility::Update(float dt){ - map::iterator it=cards.begin(); - while(it != cards.end()){ - MTGCardInstance * card = (*it).first; - it++; - int doDelete = 1; - for (int i = 0; i < 2; i++){ - Player * p = game->players[i]; - MTGGameZone * zones[] = {p->game->inPlay}; - for (int k = 0; k < 1; k++){ - MTGGameZone * zone = zones[k]; - if (zone->hasCard(card)){ - doDelete = 0; - break; - } - } - } - if (doDelete || !canBeInList(card)){ -#if defined (WIN32) || defined (LINUX) -OutputDebugString("DELETE FRO LISTMAINTAINER\n"); -#endif - cards.erase(card); - removed(card); - } - } - for (int i = 0; i < 2; i++){ - Player * p = game->players[i]; - MTGGameZone * zones[] = {p->game->inPlay}; - for (int k = 0; k < 1; k++){ - MTGGameZone * zone = zones[k]; - for (int j = 0; j < zone->nb_cards; j++){ - if (canBeInList(zone->cards[j])){ - if(cards.find(zone->cards[j]) == cards.end()){ - cards[zone->cards[j]] = true; - added(zone->cards[j]); - } - } - } - } - } - } - - //Destroy the spell -> remove all targets - int ListMaintainerAbility::destroy(){ - map::iterator it; - - for ( it=cards.begin() ; it != cards.end(); it++ ){ - removed((*it).first); - } - cards.clear(); - return 1; - } +#include "../include/debug.h" +#include "../include/MTGAbility.h" +#include "../include/ManaCost.h" +#include "../include/MTGGameZones.h" +#include "../include/AllAbilities.h" +#include "../include/Damage.h" +#include "../include/TargetChooser.h" +#include "../include/CardGui.h" +#include "../include/MTGDeck.h" + +int AbilityFactory::destroyAllFromTypeInPlay(const char * type, MTGCardInstance * source, int bury){ + GameObserver * game = GameObserver::GetInstance(); + for (int i = 0; i < 2 ; i++){ + for (int j = 0; j < game->players[i]->game->inPlay->nb_cards; j++){ + MTGCardInstance * current = game->players[i]->game->inPlay->cards[j]; + if (current->hasType(type)){ + if (bury){ + game->players[i]->game->putInGraveyard(current); + }else{ + game->mLayers->stackLayer()->addPutInGraveyard(current); + } + } + } + } + return 1; +} + +int AbilityFactory::destroyAllFromColorInPlay(int color, MTGCardInstance * source, int bury){ + GameObserver * game = GameObserver::GetInstance(); + for (int i = 0; i < 2 ; i++){ + for (int j = 0; j < game->players[i]->game->inPlay->nb_cards; j++){ + MTGCardInstance * current = game->players[i]->game->inPlay->cards[j]; + if (current->hasColor(color)){ + if (bury){ + game->players[i]->game->putInGraveyard(current); + }else{ + game->mLayers->stackLayer()->addPutInGraveyard(current); + } + } + } + } + return 1; +} + +int AbilityFactory::putInPlayFromZone(MTGCardInstance * card, MTGGameZone * zone, Player * p){ + Spell * spell = NEW Spell(card); + p->game->putInZone(card, zone, p->game->stack); + spell->resolve(); + delete spell; + return 1; +} + +//Some basic functionnalities that can be added automatically in the text file +int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){ + int dryMode = 0; + if (!spell) dryMode = 1; + GameObserver * game = GameObserver::GetInstance(); + if (!card) card = spell->source; + MTGCardInstance * target = card->target; + if (!target) target = card; + string magicText = card->magicText; + if (card->alias && magicText.size() == 0){ + //An awful way to gat access to the aliasedcard + magicText = GameObserver::GetInstance()->players[0]->game->collection->getCardById(card->alias)->magicText; + } + string s; + int size = magicText.size(); + if (size == 0) return 0; + unsigned int found; + int result = id; + + + while (magicText.size()){ + found = magicText.find("\n"); + if (found != string::npos){ + s = magicText.substr(0,found); + magicText = magicText.substr(found+1); + }else{ + s = magicText; + magicText = ""; + } +#if defined (WIN32) || defined (LINUX) + char buf[4096]; + sprintf(buf, "AUTO ACTION: %s\n", s.c_str()); + OutputDebugString(buf); +#endif + + TargetChooser * tc = NULL; + int doTap = 0; + string lordType = ""; + + //Tap in the cost ? + if (s.find("{t}") != string::npos) doTap = 1; + + //Target Abilities + found = s.find("target("); + if (found != string::npos){ + int end = s.find(")"); + string target = s.substr(found + 7,end - found - 7); + TargetChooserFactory tcf; + tc = tcf.createTargetChooser(target, card); + + } + + //Lord + found = s.find("lord("); + if (found != string::npos){ + if (dryMode) return BAKA_EFFECT_GOOD; + unsigned int end = s.find(")", found+5); + if (end != string::npos){ + lordType = s.substr(found+5,end-found-5).c_str(); + } + } + + //Champion. Very basic, needs to be improved ! + found = s.find("champion(name:"); + if (found != string::npos){ + if (dryMode) return BAKA_EFFECT_GOOD; + unsigned int end = s.find(")", found+14); + if (end != string::npos){ + string type = s.substr(found+14,end-found-14).c_str(); + game->addObserver(NEW APlagueRats(id,card,type.c_str())); + result++; + continue; + } + } + + //Untapper (Ley Druid...) + found = s.find("untap"); + if (found != string::npos){ + if (dryMode) return BAKA_EFFECT_GOOD; + ManaCost * cost = ManaCost::parseManaCost(s); + if (tc){ + game->addObserver(NEW AUntaper(id, card, cost, tc)); + }else{ + target->tapped = 0; + } + + result++; + continue; + } + + //Tapper (icy manipulator) + found = s.find("tap"); + if (found != string::npos){ + if (dryMode) return BAKA_EFFECT_GOOD; + ManaCost * cost = ManaCost::parseManaCost(s); + if (tc){ + game->addObserver(NEW ATapper(id, card, cost, tc)); + }else{ + target->tapped = 1; + } + + result++; + continue; + } + //Tentative Destroyall not working char is not compatible with string variable + //found = s.find("destroyall("); + //if (found != string::npos){ + // if (dryMode) return BAKA_EFFECT_GOOD; + // unsigned int end = s.find(")", found+11); + // if (end != string::npos){ + // string type = s.substr(found+11,end-found-11).c_str(); + // destroyAllFromTypeInPlay(type.c_str(), card); + // result++; + // continue; + //} + + //Regeneration + found = s.find("}:regenerate"); + if (found != string::npos){ + if (dryMode) return BAKA_EFFECT_GOOD; + ManaCost * cost = ManaCost::parseManaCost(s); + + if (lordType.size() > 0){ + game->addObserver(NEW ALord(id,card,lordType.c_str(),0,0,-1,cost)); + }else{ + + if (tc){ + //TODO + }else{ + game->addObserver(NEW AStandardRegenerate(id, card, target, cost)); + //TODO death ward ! + } + } + result++; + continue; + } + //Bury + found = s.find("bury"); + if (found != string::npos){ + if (dryMode) return BAKA_EFFECT_BAD; + if (tc){ + game->addObserver(NEW ABurier(id, card,tc)); + }else{ + target->controller()->game->putInGraveyard(target); + } + result++; + continue; + } + //Destroy + found = s.find("destroy"); + if (found != string::npos){ + if (dryMode) return BAKA_EFFECT_BAD; + if (tc){ + game->addObserver(NEW ADestroyer(id, card,tc)); + }else{ + game->mLayers->stackLayer()->addPutInGraveyard(target); + } + result++; + continue; + } + + //Summon + + //Reveal Take Target and put in in hand (should be also able to target hand since some card needs you to reveal a card in your hand + + //Damage + found = s.find("damage"); + if (found != string::npos){ + unsigned int start = s.find(":",found); + unsigned int end = s.find(" ",start); + int damage; + ManaCost * cost = ManaCost::parseManaCost(s); + if (end != string::npos){ + damage = atoi(s.substr(start+1,end-start-1).c_str()); + }else{ + damage = atoi(s.substr(start+1).c_str()); + } + if (dryMode) return BAKA_EFFECT_BAD; + if (tc){ + game->addObserver(NEW ADamager(id, card, cost, damage, tc,doTap)); + }else{ + delete cost; + game->mLayers->stackLayer()->addDamage(card,spell->getNextDamageableTarget(), damage); + } + result++; + continue; + } + + //gain/lose life + found = s.find("life"); + if (found != string::npos){ + unsigned int start = s.find(":",found); + unsigned int end = s.find(" ",start); + int life; + ManaCost * cost = ManaCost::parseManaCost(s); + if (end != string::npos){ + life = atoi(s.substr(start+1,end-start-1).c_str()); + }else{ + life = atoi(s.substr(start+1).c_str()); + } + if (dryMode) return BAKA_EFFECT_GOOD; + if (tc){ + //TODO ? + }else{ + if (cost->getConvertedCost() == 0 && !doTap){ + delete cost; + card->controller()->life+=life; + }else{ + //TODO; + } + } + result++; + continue; + } + + //Draw + found = s.find("draw"); + if (found != string::npos){ + unsigned int start = s.find(":",found); + unsigned int end = s.find(" ",start); + int nbcards; + ManaCost * cost = ManaCost::parseManaCost(s); + if (end != string::npos){ + nbcards = atoi(s.substr(start+1,end-start-1).c_str()); + }else{ + nbcards = atoi(s.substr(start+1).c_str()); + } + if (dryMode) return BAKA_EFFECT_GOOD; + if (tc){ + //TODO ? + }else{ + if (cost->getConvertedCost() == 0){ + delete cost; + game->mLayers->stackLayer()->addDraw(card->controller(),nbcards); + }else{ + game->addObserver(NEW ADrawer(id,card,cost,nbcards,doTap)); + } + } + result++; + continue; + } + + //Change Power/Toughness + found = s.find("/"); + if (found != string::npos){ + unsigned int start = s.find(":"); + if (start == string::npos) start = -1; + int power = atoi(s.substr(start+1,size-found).c_str()); + unsigned int end = s.find(" ",start); + int toughness; + if (end != string::npos){ + toughness = atoi(s.substr(found+1,end-found-1).c_str()); + }else{ + toughness = atoi(s.substr(found+1).c_str()); + } + if (dryMode){ + if (power >=0 && toughness >= 0 ) return BAKA_EFFECT_GOOD; + return BAKA_EFFECT_BAD; + } + int limit = 0; + unsigned int limit_str = s.find("limit:"); + if (limit_str != string::npos){ + limit = atoi(s.substr(limit_str+6).c_str()); + } + ManaCost * cost = ManaCost::parseManaCost(s); + + if (lordType.size() > 0){ + game->addObserver(NEW ALord(id,card,lordType.c_str(),power,toughness)); + }else{ + if(tc){ + game->addObserver(NEW ATargetterPowerToughnessModifierUntilEOT(id, card,power,toughness, cost, tc)); + }else{ + if (cost->getConvertedCost() == 0){ + delete cost; + if(card->hasType("enchantment")){ + game->addObserver(NEW APowerToughnessModifier(id, card, target,power,toughness)); + }else{ + game->addObserver(NEW AInstantPowerToughnessModifierUntilEOT(id, card, target,power,toughness)); + } + }else{ + game->addObserver(NEW APowerToughnessModifierUntilEndOfTurn(id, card, target,power,toughness, cost, limit)); + } + } + } + result++; + continue; + } + + //Mana Producer + found = s.find("add"); + if (found != string::npos){ + if (dryMode) return BAKA_EFFECT_GOOD; + ManaCost * cost = ManaCost::parseManaCost(s.substr(0,found)); + ManaCost * output = ManaCost::parseManaCost(s.substr(found)); + if (cost->getConvertedCost()){ + game->addObserver(NEW AManaProducer(id, target, output, cost)); + }else{ + delete cost; + if (doTap){ + game->addObserver(NEW AManaProducer(id, target, output)); + }else{ + card->controller()->getManaPool()->add(output); + delete output; + } + + } + result++; + continue; + } + + //Gain/loose Ability + for (int j = 0; j < NB_BASIC_ABILITIES; j++){ + found = s.find(MTGBasicAbilities[j]); + if (found!= string::npos){ + int modifier = 1; + if (found > 0 && s[found-1] == '-') modifier = 0; + if (dryMode){ + if (j == DEFENDER){ + if (modifier == 1) return BAKA_EFFECT_BAD; + return BAKA_EFFECT_GOOD; + }else{ + if (modifier == 1) return BAKA_EFFECT_GOOD; + return BAKA_EFFECT_BAD; + } + } + ManaCost * cost = ManaCost::parseManaCost(s); + + if (lordType.size() > 0){ + game->addObserver(NEW ALord(id,card,lordType.c_str(),0,0,j)); + }else{ + + if (tc){ + game->addObserver(NEW ABasicAbilityModifierUntilEOT(id, card, j, cost,tc, modifier)); + }else{ + if (cost->getConvertedCost() == 0){ + delete cost; + if(card->hasType("enchantment")){ + game->addObserver(NEW ABasicAbilityModifier(id, card,target, j,modifier)); + }else{ + game->addObserver(NEW AInstantBasicAbilityModifierUntilEOT(id, card,target, j,modifier)); + } + }else{ + game->addObserver(NEW ABasicAbilityAuraModifierUntilEOT(id, card,target, cost,j,modifier)); + } + } + } + result++; + continue; + } + } + } + return result; + + +} + +void AbilityFactory::addAbilities(int _id, Spell * spell){ + MTGCardInstance * card = spell->source; + if (spell->cursor==1) card->target = spell->getNextCardTarget(); + _id = magicText(_id, spell); + int putSourceInGraveyard = 0; //For spells that are not already InstantAbilities; + + + GameObserver * game = GameObserver::GetInstance(); + int id = card->model->getId(); + if (card->alias) id = card->alias; + switch (id){ + case 1092: //Aladdin's lamp + { + AAladdinsLamp * ability = NEW AAladdinsLamp(_id, card); + game->addObserver(ability); + break; + } + case 130550: //Ancestor's chosen + { + int life = card->controller()->game->graveyard->nb_cards; + card->controller()->life+= life; + break; + } + case 1190: //Animate Artifact + { + int x = card->target->getManaCost()->getConvertedCost(); + game->addObserver(NEW AConvertToCreatureAura(_id, card,card->target,x,x)); + break; + } + case 1094: //Ank Of Mishra + { + AAnkhOfMishra * ability = NEW AAnkhOfMishra(_id,card); + game->addObserver(ability); + break; + } + case 1095: //Armageddon clock + { + AArmageddonClock * ability = NEW AArmageddonClock(_id,card); + game->addObserver(ability); + break; + } + case 106525: //Ascendant Evincar + { + game->addObserver(NEW AColorLord(_id, card,MTG_COLOR_BLACK,-1,1,1)); + game->addObserver(NEW AColorLord(_id, card,0,MTG_COLOR_BLACK,-1,-1)); + break; + } + + case 1096: //Basalt Monolith + { + int cost[] = {MTG_COLOR_ARTIFACT, 3}; + AManaProducer * ability = NEW AManaProducer(_id, card, NEW ManaCost(cost,1)); + AUntapManaBlocker * ability2 = NEW AUntapManaBlocker(_id+1, card, NEW ManaCost(cost,1)); + AUnBlocker * ability3 = NEW AUnBlocker(_id+1, card,card, NEW ManaCost(cost,1)); + + game->addObserver(ability); + game->addObserver(ability2); + game->addObserver(ability3); + break; + } + case 1097: //Black Vise + { + game->addObserver( NEW ALifeZoneLink(_id ,card, MTG_PHASE_UPKEEP, 4)); + break; + } + case 1191: //Blue Elemental Blast + { + if (card->target){ + card->target->controller()->game->putInGraveyard(card->target); + }else{ + Spell * starget = spell->getNextSpellTarget(); + game->mLayers->stackLayer()->Fizzle(starget); + } + break; + } + case 1099: //Brass Man + { + int cost[] = {MTG_COLOR_ARTIFACT, 1}; + game->addObserver(NEW AUntapManaBlocker(_id, card, NEW ManaCost(cost,1))); + break; + } + case 1237: //Channel + { + game->addObserver(NEW AChannel(_id, card)); + break; + } + case 1282: //Chaoslace + { + if (card->target){ + card->target->setColor(MTG_COLOR_RED, 1); + }else{ + Spell * starget = spell->getNextSpellTarget(); + starget->source->setColor(MTG_COLOR_RED, 1); + } + break; + } + case 1335: //Circle of protection : black + { + game->addObserver(NEW ACircleOfProtection( _id,card, MTG_COLOR_BLACK)); + break; + } + case 1336: //Circle of protection : blue + { + game->addObserver(NEW ACircleOfProtection( _id,card, MTG_COLOR_BLUE)); + break; + } + case 1337: //Circle of protection : green + { + game->addObserver(NEW ACircleOfProtection( _id,card, MTG_COLOR_GREEN)); + break; + } + case 1338: //Circle of protection : red + { + game->addObserver(NEW ACircleOfProtection( _id,card, MTG_COLOR_RED)); + break; + } + case 1339: //Circle of protection : white + { + game->addObserver(NEW ACircleOfProtection( _id,card, MTG_COLOR_WHITE)); + break; + } + case 1101: //clockwork Beast + { + game->addObserver(NEW AClockworkBeast(_id,card)); + break; + } + case 1102: //Conservator + { + game->addObserver(NEW AConservator(_id,card)); + break; + } + case 1196: //Counterspell + { + Spell * starget = spell->getNextSpellTarget(); + if (starget) game->mLayers->stackLayer()->Fizzle(starget); + break; + } + case 1197: //Creature Bond + { + game->addObserver(NEW ACreatureBond(_id,card, card->target)); + break; + } + case 1103: //Crystal Rod + { + int cost[] = {MTG_COLOR_BLUE, 1}; + ASpellCastLife* ability = NEW ASpellCastLife(_id, card, MTG_COLOR_WHITE,NEW ManaCost(cost,1) , 1); + game->addObserver(ability); + break; + } + case 1151: //Deathgrip + { + int _cost[] = {MTG_COLOR_BLACK, 2}; + game->addObserver(NEW ASpellCounterEnchantment(_id, card, NEW ManaCost(_cost, 1),MTG_COLOR_GREEN)); + break; + } + case 1152: //Deathlace + { + if (card->target){ + card->target->setColor(MTG_COLOR_BLACK, 1); + }else{ + Spell * starget = spell->getNextSpellTarget(); + starget->source->setColor(MTG_COLOR_BLACK, 1); + } + break; + } + case 1105: //dingus Egg + { + ADingusEgg * ability = NEW ADingusEgg(_id,card); + game->addObserver(ability); + break; + } + case 1106: //Disrupting Scepter + { + ADisruptingScepter * ability = NEW ADisruptingScepter(_id,card); + game->addObserver(ability); + break; + } + case 1284: //Dragon Whelp + { + game->addObserver(NEW ADragonWhelp(_id,card)); + break; + } + case 1108: //Ebony Horse + { + AEbonyHorse * ability = NEW AEbonyHorse(_id,card); + game->addObserver(ability); + break; + } + case 1345: //Farmstead + { + game->addObserver(NEW AFarmstead(_id, card,card->target)); + break; + } + case 1291: //Fireball + { + int x = spell->cost->getConvertedCost() - 1; //TODO BETTER + game->addObserver(NEW AFireball(_id, card,spell, x)); + break; + } + case 1245: //Force of Nature + { + game->addObserver(NEW AForceOfNature(_id,card)); + break; + } + case 1110: //Glasses Of Urza + { + AGlassesOfUrza * ability = NEW AGlassesOfUrza(_id,card); + game->addObserver(ability); + break; + } + case 1112: //Howling Mine + { + game->addObserver(NEW AHowlingMine(_id, card)); + break; + } + case 1252: //Instill Energy + { + game->addObserver(NEW AUntaperOnceDuringTurn(_id, card, card->target, NEW ManaCost())); + break; + } + case 1113: //Iron Star + { + int cost[] = {MTG_COLOR_ARTIFACT, 1}; + ASpellCastLife* ability = NEW ASpellCastLife(_id, card, MTG_COLOR_RED,NEW ManaCost(cost,1) , 1); + game->addObserver(ability); + break; + } + case 1351: // Island Sancturay + { + game->addObserver(NEW AIslandSanctuary(_id, card)); + break; + } + case 1114: //Ivory cup + { + int cost[] = {MTG_COLOR_ARTIFACT, 1}; + ASpellCastLife* ability = NEW ASpellCastLife(_id, card, MTG_COLOR_WHITE,NEW ManaCost(cost,1) , 1); + game->addObserver(ability); + break; + } + case 1115: //Ivory Tower + { + game->addObserver(NEW ALifeZoneLink(_id ,card, MTG_PHASE_UPKEEP, 4, 1, 1)); + break; + } + case 1117: //Jandors Ring + { + game->addObserver(NEW AJandorsRing( _id, card)); + break; + } + case 1121: //Kormus Bell + { + game->addObserver(NEW AConvertLandToCreatures(id, card, "swamp")); + break; + } + case 1254: //Kudzu + { + game->addObserver(NEW AKudzu(id, card, card->target)); + break; + } + case 1256: //LifeForce + { + int _cost[] = {MTG_COLOR_GREEN, 2}; + game->addObserver(NEW ASpellCounterEnchantment(_id, card, NEW ManaCost(_cost, 1),MTG_COLOR_BLACK)); + break; + } + case 1257: //Lifelace + { + if (card->target){ + card->target->setColor(MTG_COLOR_GREEN, 1); + }else{ + Spell * starget = spell->getNextSpellTarget(); + starget->source->setColor(MTG_COLOR_GREEN, 1); + } + break; + } + case 1205: //Lifetap + { + game->addObserver(NEW AGiveLifeForTappedType(_id, card, "forest")); + break; + } + case 1259: //Living lands + { + game->addObserver(NEW AConvertLandToCreatures(id, card, "forest")); + break; + } + case 1124: //Mana Vault + { + int output[] = {MTG_COLOR_ARTIFACT, 3}; + game->addObserver(NEW AManaProducer(_id,card,NEW ManaCost(output,1))); + int cost[] = {MTG_COLOR_ARTIFACT, 4}; + game->addObserver(NEW AUntapManaBlocker(_id+1, card, NEW ManaCost(cost,1))); + game->addObserver(NEW ARegularLifeModifierAura(_id+2, card, card, MTG_PHASE_DRAW, -1, 1)); + break; + } + case 1126:// Millstone + { + game->addObserver( NEW AMillstone(_id ,card)); + break; + } + case 1215: //Power Leak + { + game->addObserver( NEW APowerLeak(_id ,card, card->target)); + break; + } + case 1311: //Power Surge + { + game->addObserver( NEW APowerSurge(_id ,card)); + break; + } + case 1358: //Purelace + { + if (card->target){ + card->target->setColor(MTG_COLOR_WHITE, 1); + }else{ + Spell * starget = spell->getNextSpellTarget(); + starget->source->setColor(MTG_COLOR_WHITE, 1); + } + break; + } + case 1312: //Red Elemental Blast + { + if (card->target){ + card->target->controller()->game->putInGraveyard(card->target); + }else{ + Spell * starget = spell->getNextSpellTarget(); + game->mLayers->stackLayer()->Fizzle(starget); + } + break; + } + case 1136: //Soul Net + { + game->addObserver( NEW ASoulNet(_id ,card)); + break; + } + case 1139: //The Rack + { + game->addObserver( NEW ALifeZoneLink(_id ,card, MTG_PHASE_UPKEEP, -3)); + break; + } + case 1140: //Throne of bones + { + int cost[] = {MTG_COLOR_ARTIFACT, 1}; + ASpellCastLife* ability = NEW ASpellCastLife(_id, card, MTG_COLOR_BLACK,NEW ManaCost(cost,1) , 1); + game->addObserver(ability); + break; + } + case 1142: //Wooden Sphere + { + int cost[] = {MTG_COLOR_ARTIFACT, 1}; + ASpellCastLife* ability = NEW ASpellCastLife(_id, card, MTG_COLOR_GREEN,NEW ManaCost(cost,1) , 1); + game->addObserver(ability); + break; + } + case 1143: //Animate Dead + { + game->addObserver(NEW AAnimateDead(_id, card, card->target)); + break; + } + case 1144: //Bad moon + { + game->addObserver(NEW ABadMoon(_id,card)); + break; + } + case 1148 : //Cursed lands + { + game->addObserver(NEW AWanderlust(_id, card, card->target)); + break; + } + case 1156: //Drain Life + { + Damageable * target = spell->getNextDamageableTarget(); + int x = spell->cost->getConvertedCost() - 2; //TODO Fix that !!! + X should be only black mana, that needs to be checked ! + game->mLayers->stackLayer()->addDamage(card, target, x); + if (target->life < x) x = target->life; + game->currentlyActing()->life+=x; + break; + } + case 1159: //Erg Raiders + { + AErgRaiders* ability = NEW AErgRaiders(_id, card); + game->addObserver(ability); + break; + } + case 1164: //Howl from beyond + { + int x = spell->cost->getConvertedCost() - 1; //TODO, this is not enough, Spells shouls have a function like "xCost" because the spell might cost more than expected to launch + AInstantPowerToughnessModifierUntilEOT * ability = NEW AInstantPowerToughnessModifierUntilEOT( _id, card, card->target, x, 0); + game->addObserver(ability); + break; + } + case 1202: //Hurkyl's Recall + { + Player * player = spell->getNextPlayerTarget(); + if (player){ + for (int i = 0; i < 2; i++){ + MTGInPlay * inplay = game->players[i]->game->inPlay; + for (int j= inplay->nb_cards -1 ; j >=0 ; j--){ + MTGCardInstance * card = inplay->cards[j]; + if (card->owner == player && card->hasType("artifact")){ + player->game->putInZone(card, inplay, player->game->hand); + } + } + } + } + break; + } + case 1165: //Hypnotic Specter + { + game->addObserver(NEW AHypnoticSpecter( _id, card)); + break; + } + case 1258: //Living Artifact + { + game->addObserver(NEW ALivingArtifact( _id, card, card->target)); + break; + } + case 1166: //Lord Of The Pit + { + game->addObserver(NEW ALordOfThePit( _id, card)); + break; + } + case 1209: //Mana Short + { + Player * player = spell->getNextPlayerTarget(); + if (player){ + MTGInPlay * inplay = player->game->inPlay; + for (int i = 0; i < inplay->nb_cards; i++){ + MTGCardInstance * current = inplay->cards[i]; + if (current->hasType("land")) current->tapped = 1; + } + player->getManaPool()->init(); + } + break; + } + case 1167: //Mind Twist + { + int xCost = spell->cost->getConvertedCost() - 1; + for (int i = 0; i < xCost; i++){ + game->opponent()->game->discardRandom(game->opponent()->game->hand); + } + break; + } + case 1170: //Nightmare + { + game->addObserver(NEW ANightmare(_id, card)); + break; + } + case 1171: //Paralysis + { + int cost[] = {MTG_COLOR_ARTIFACT, 4}; + game->addObserver(NEW AUntapManaBlocker(_id, card,card->target, NEW ManaCost(cost,1))); + card->target->tapped = 1; + break; + } + case 1172: //Pestilence + { + game->addObserver(NEW APestilence(_id, card)); + break; + } + /*case 1173: //Plague Rats + { + game->addObserver(NEW APlagueRats(_id, card, "Plague Rats")); + break; + } + */ + case 1174: //Raise Dead + { + MTGPlayerCards * zones = game->currentlyActing()->game; + zones->putInZone(card->target,zones->graveyard,zones->hand); + } + case 1176: //Sacrifice + { + ASacrifice * ability = NEW ASacrifice(_id, card, card->target); + game->addObserver(ability); + break; + } + case 1224: //Spell Blast + { + int x = spell->cost->getConvertedCost() - 1; + Spell * starget = spell->getNextSpellTarget(); + if (starget){ + if (starget->cost->getConvertedCost() <= x) game->mLayers->stackLayer()->Fizzle(starget); + } + break; + } + case 1185: //Warp Artifact + { + game->addObserver(NEW ARegularLifeModifierAura(_id, card, card->target, MTG_PHASE_UPKEEP, -1)); + break; + } + case 1192: //BrainGeyser + { + Player * player = ((Player * )spell->targets[0]); + int x = spell->cost->getConvertedCost() - 2; + for (int i = 0; i < x ; i++){ + player->game->drawFromLibrary(); + } + break; + } + case 1194: //Control Magic + { + game->addObserver(NEW ATakeControlAura(_id, card, card->target)); + break; + } + + case 1200 : //Feedback + { + game->addObserver(NEW AWanderlust(_id, card, card->target)); + break; + } + case 129601: //Icy Manipulator + { + int cost[] = {MTG_COLOR_ARTIFACT, 1}; + TypeTargetChooser * tc = new TypeTargetChooser("artifact",card); + tc->addType("land"); + tc->addType("creature"); + game->addObserver(NEW ATapper(_id,card,NEW ManaCost(cost, 1),tc)); + break; + } + + case 1203: //Island Fish + { + int cost[] = {MTG_COLOR_BLUE, 3}; + game->addObserver(NEW AUntapManaBlocker(_id, card, NEW ManaCost(cost,1))); + game->addObserver(NEW AStrongLandLinkCreature(_id, card, "island")); + break; + } + case 1214: //Pirate Ship + { + game->addObserver(NEW AStrongLandLinkCreature(_id, card, "island")); + game->addObserver(NEW ADamager(_id+1, card, NEW ManaCost(), 1)); + break; + } + case 1218: //Psychic Venom + { + game->addObserver(NEW APsychicVenom(_id, card, card->target)); + break; + } + case 1220: //Sea Serpent + { + game->addObserver(NEW AStrongLandLinkCreature(_id, card, "island")); + break; + } + case 1315: //Sedge Troll + { + game->addObserver( NEW ASedgeTroll(_id, card)); + break; + } + case 1221: //Serendib Efreet + { + game->addObserver( NEW ASerendibEfreet(_id, card)); + break; + } + case 1226: //Steal Artifact + { + game->addObserver( NEW AControlStealAura(_id, card, card->target)); + break; + } + case 1228: //Unstable mutation + { + game->addObserver(NEW APowerToughnessModifier(_id, card, card->target, 3, 3)); + game->addObserver(NEW APowerToughnessModifierRegularCounter(_id, card, card->target, MTG_PHASE_UPKEEP, -1, -1)); + break; + } + case 1229: //Unsummon + { + MTGPlayerCards * zones = card->target->controller()->game; + zones->putInZone(card->target,zones->inPlay,zones->hand); + break; + } + case 1235: //Aspect of Wolf + { + game->addObserver(NEW AAspectOfWolf(_id, card, card->target)); + break; + } + case 1236: //Birds of Paradise + { + for (int i = MTG_COLOR_GREEN; i <= MTG_COLOR_WHITE; i++){ + int output[]={i,1}; + game->addObserver(NEW AManaProducer(_id + i, card, NEW ManaCost(output,1))); + } + break; + } + case 1240: //Crumble + { + card->target->controller()->game->putInGraveyard(card->target); + card->target->controller()->life+= card->target->getManaCost()->getConvertedCost(); + break; + } + case 1251: //Hurricane + { + int x = spell->cost->getConvertedCost() - 1; + for (int i = 0; i < 2 ; i++){ + game->mLayers->stackLayer()->addDamage(card, game->players[i], x); + for (int j = 0; j < game->players[i]->game->inPlay->nb_cards; j++){ + MTGCardInstance * current = game->players[i]->game->inPlay->cards[j]; + if (current->basicAbilities[FLYING] && current->isACreature()){ + game->mLayers->stackLayer()->addDamage(card, current, x); + } + } + } + break; + } + case 1262: //Regeneration + { + int cost[] = {MTG_COLOR_GREEN, 1}; + game->addObserver(NEW AStandardRegenerate(_id,card,card->target,NEW ManaCost(cost,1))); + break; + } + case 1263: //Regrowth + { + MTGPlayerCards * zones = game->currentlyActing()->game; + zones->putInZone(card->target,zones->graveyard,zones->hand); + break; + } + case 1266: //stream of life + { + int x = spell->cost->getConvertedCost() - 1; //TODO Improve that ! + spell->getNextPlayerTarget()->life += x; + break; + } + case 1270: //tranquility + { + destroyAllFromTypeInPlay("enchantment", card); + break; + } + case 1271: //Tsunami + { + destroyAllFromTypeInPlay("island", card); + break; + } + case 1231: //Volcanic Eruption + { + int x = spell->cost->getConvertedCost() - 3; + int _x = x; + MTGCardInstance * target = spell->getNextCardTarget(); + while(target && _x){ + game->mLayers->stackLayer()->addPutInGraveyard(target); + _x--; + target = spell->getNextCardTarget(target); + } + x-=_x; + for (int i = 0; i < 2 ; i++){ + game->mLayers->stackLayer()->addDamage(card, game->players[i], x); + for (int j = 0; j < game->players[i]->game->inPlay->nb_cards; j++){ + MTGCardInstance * current = game->players[i]->game->inPlay->cards[j]; + if (current->isACreature()){ + game->mLayers->stackLayer()->addDamage(card, current, x); + } + } + } + break; + } + case 1278: //Web + { + game->addObserver(NEW APowerToughnessModifier(_id, card, card->target, 0,2)); + game->addObserver(NEW ABasicAbilityModifier(_id + 1, card, card->target, REACH)); + break; + } + case 1280: //Atog + { + game->addObserver(NEW AAtog(_id, card)); + break; + } + case 1285: //Dwarven Warriors{ + { + CreatureTargetChooser * tc = NEW CreatureTargetChooser(card); + tc->maxpower = 2; + game->addObserver(NEW ABasicAbilityModifierUntilEOT(_id, card, UNBLOCKABLE, NULL,tc)); + break; + } + case 1288: //EarthBind + { + game->addObserver(NEW AEarthbind(_id, card, card->target)); + break; + } + case 1289: //earthquake + { + int x = spell->cost->getConvertedCost() - 1; + for (int i = 0; i < 2 ; i++){ + game->mLayers->stackLayer()->addDamage(card, game->players[i], x); + for (int j = 0; j < game->players[i]->game->inPlay->nb_cards; j++){ + MTGCardInstance * current = game->players[i]->game->inPlay->cards[j]; + if (!current->basicAbilities[FLYING] && current->isACreature()){ + game->mLayers->stackLayer()->addDamage(card, current, x); + } + } + } + break; + } + case 1344: //Eye for an Eye + { + Damage * damage = spell->getNextDamageTarget(); + if (damage){ + game->mLayers->stackLayer()->addDamage(card,damage->source->controller(),damage->damage); + } + break; + } + case 1243: //Fastbond + { + game->addObserver(NEW AFastbond(_id, card)); + break; + } + case 1293: //FlashFires + { + destroyAllFromTypeInPlay("plains", card); + break; + } + case 1301: // Keldon Warlord + { + game->addObserver(NEW AKeldonWarlord(_id, card)); + break; + } + case 1302: //Kird Ape + { + game->addObserver(NEW AKirdApe(_id, card)); + break; + } + case 1309: //Orcish Artillery + { + game->addObserver(NEW AOrcishArtillery(_id, card)); + break; + } + case 1310: //Orcish Oriflame + { + game->addObserver(NEW AOrcishOriflame(_id, card)); + break; + } + case 1317: //ShatterStorm + { + destroyAllFromTypeInPlay("artifact", card, 1); + break; + } + case 1326: //Wheel of fortune + { + for (int i = 0; i < 2; i++){ + MTGLibrary * library = game->players[i]->game->library; + MTGHand * hand = game->players[i]->game->hand; + for (int j = hand->nb_cards-1; j>=0; j--){ + game->players[i]->game->putInGraveyard(hand->cards[j]); + } + for(int j = 0; j < 7; j++){ + game->players[i]->game->drawFromLibrary(); + } + } + break; + } + case 1328: //Armageddon + { + destroyAllFromTypeInPlay("land", card); + break; + } + case 1331: //Black Ward + { + game->addObserver(NEW AProtectionFrom( _id,card, card->target, MTG_COLOR_BLACK)); + break; + } + case 1333: //Blue Ward + { + game->addObserver(NEW AProtectionFrom( _id,card, card->target, MTG_COLOR_BLUE)); + break; + } + case 1334: //Castle + { + game->addObserver(NEW ACastle(_id,card)); + break; + } + case 1238: //Cockatrice + { + game->addObserver(NEW AOldSchoolDeathtouch(_id,card)); + break; + } + case 1341: //Crusade: + { + game->addObserver(NEW ABadMoon(_id,card, MTG_COLOR_WHITE)); + break; + + } + case 1346: //Green Ward + { + game->addObserver(NEW AProtectionFrom( _id,card, card->target, MTG_COLOR_GREEN)); + break; + } + case 1352: //Karma + { + game->addObserver(NEW AKarma(_id, card)); + break; + } + case 1355: //Northern Paladin + { + game->addObserver(NEW ANorthernPaladin(_id, card)); + break; + } + case 1359: //Red Ward + { + game->addObserver(NEW AProtectionFrom( _id,card, card->target, MTG_COLOR_RED)); + break; + } + case 1360: //Resurrection + { + Player * p = card->controller(); + AbilityFactory af; + af.putInPlayFromZone(card->target, p->game->graveyard, p); + break; + } + case 1362: //Reverse polarity + { + ActionStack * as = game->mLayers->stackLayer(); + Player * controller = card->controller(); + Damage * current = ((Damage *)as->getNext(NULL,ACTION_SPELL, RESOLVED_OK)); + while(current){ + if (current->target == controller && current->source->hasType("artifact")){ + controller->life+= current->damage * 2; + } + current = ((Damage *)as->getNext(current,ACTION_SPELL, RESOLVED_OK)); + } + break; + } + case 1225: //Stasis + { + game->addObserver(NEW AStasis(_id, card)); + break; + } + + case 1367: //Sword to Plowshares + { + card->target->controller()->life+= card->target->power; + card->target->controller()->game->inPlay->removeCard(card->target); + break; + } + case 1182: //Terror + { + if (card->target->hasColor(MTG_COLOR_BLACK) || card->target->hasSubtype("artifact")){ + }else{ + card->target->controller()->game->putInGraveyard(card->target); + } + break; + } + case 1267: //Thicket Basilic + { + game->addObserver(NEW AOldSchoolDeathtouch(_id,card)); + break; + } + case 1227: //Toughtlace + { + if (card->target){ + card->target->setColor(MTG_COLOR_BLUE, 1); + }else{ + Spell * starget = spell->getNextSpellTarget(); + starget->source->setColor(MTG_COLOR_BLUE, 1); + } + break; + } + case 1371: //White Ward + { + game->addObserver(NEW AProtectionFrom( _id,card, card->target, MTG_COLOR_WHITE)); + break; + } + case 1372: //Wrath of God + { + destroyAllFromTypeInPlay("creature", card); //TODO -> bury !!! + break; + } + + + // Addons ALA + + case 175114: // Master of Etherium + { + game->addObserver(NEW ACreaturePowerToughnessModifierForAllTypeControlled(_id,card,"artifact")); + break; + } + + case 174989: // Wild Nacatl + { + game->addObserver(NEW AGenericKirdApe(_id,card,"plains",1,1)); + game->addObserver(NEW AGenericKirdApe(_id,card,"moutain",1,1)); + break; + } + + //Addons The Dark + + case 1797: //Inferno does 6 damage to all players and all creatures. + { + for (int i = 0; i < 2 ; i++){ + game->mLayers->stackLayer()->addDamage(card, game->players[i], 6); + for (int j = 0; j < game->players[i]->game->inPlay->nb_cards; j++){ + MTGCardInstance * current = game->players[i]->game->inPlay->cards[j]; + if (current->isACreature()){ + game->mLayers->stackLayer()->addDamage(card, current, 6); + } + } + } + break; + } + + case 1773 : //People of the Woods + { + game->addObserver(NEW APeopleOfTheWoods(_id, card)); + break; + } + + case 1818: //Tivadar's Crusade + { + destroyAllFromTypeInPlay("goblin", card); + break; + } + + //Addons Legends + case 1470: //Acid Rain + { + destroyAllFromTypeInPlay("forest", card); + break; + } + case 1427: //Abomination + { + game->addObserver(NEW AAbomination(_id,card)); + break; + } + case 1533: //Livingplane + { + game->addObserver(NEW AConvertLandToCreatures(id, card, "land")); + break; + } + case 1607: //Divine Offering + { + card->target->controller()->game->putInGraveyard(card->target); + game->currentlyActing()->life+= card->target->getManaCost()->getConvertedCost(); + break; + } + case 1625: //Lifeblood + { + game->addObserver(NEW AGiveLifeForTappedType (_id, card, "island")); + break; + } + //Addons ICE-AGE Cards + case 2631: //Jokulhaups + { + destroyAllFromTypeInPlay("artifact", card); + destroyAllFromTypeInPlay("creature", card); + destroyAllFromTypeInPlay("land", card); + break; + } + + case 2650: //Pyroclasm Need to be improved copied from hurricane with does 0 dammage to player and does 2 dammage to each creature + { + int x = 2; + for (int i = 0; i < 2 ; i++){ + game->mLayers->stackLayer()->addDamage(card, game->players[i], 0);// To be removed ? + for (int j = 0; j < game->players[i]->game->inPlay->nb_cards; j++){ + MTGCardInstance * current = game->players[i]->game->inPlay->cards[j]; + if (current->isACreature()){ + game->mLayers->stackLayer()->addDamage(card, current, x); + } + } + } + break; + } + case 2660: //Word of Blasting + { + card->target->controller()->game->putInGraveyard(card->target); + card->target->controller()->life-= card->target->getManaCost()->getConvertedCost(); + break; + } + case 2443: //Dark Banishing + { + if (card->target->hasColor(MTG_COLOR_BLACK)){ + }else{ + card->target->controller()->game->putInGraveyard(card->target); + } + break; + } + case 2593: //Thoughtleech + { + game->addObserver(NEW AGiveLifeForTappedType (_id, card, "island")); + break; + } + case 2484: //Songs of the Damned + { + int mana = card->controller()->game->graveyard->countByType("creature"); + game->currentlyActing()->getManaPool()->add(MTG_COLOR_BLACK, mana); + break; + } + case 2606: //Anarchy + { + destroyAllFromColorInPlay(MTG_COLOR_WHITE, card); + break; + } + case 2474: //Minion of Leshrac + { + game->addObserver(NEW AMinionofLeshrac( _id, card)); + break; + } + case 2421: //Shield of the Age + { + game->addObserver(NEW AShieldOfTheAge( _id, card)); + break; + } + case 2487: //Spoil of Evil + { + int mana_cr = game->opponent()->game->graveyard->countByType("creature"); + int mana_ar = game->opponent()->game->graveyard->countByType("artifact"); + int spoil = mana_ar + mana_cr; + game->currentlyActing()->getManaPool()->add(MTG_COLOR_ARTIFACT, spoil); + game->currentlyActing()->life+= spoil; + break; + } + case 2435: //Whalebone Glider + { + int cost[] = {MTG_COLOR_ARTIFACT,2}; + CreatureTargetChooser * tc = NEW CreatureTargetChooser(card); + tc->maxpower = 3; + game->addObserver(NEW ABasicAbilityModifierUntilEOT(_id, card, FLYING, NEW ManaCost(cost,1),tc)); + break; + } + case 2393: //Aegis of the Meek work but work also for 0/1 creatures... :D + { + int cost[] = {MTG_COLOR_ARTIFACT,1}; + CreatureTargetChooser * tc = NEW CreatureTargetChooser(card); + tc->maxpower = 1; + tc->maxtoughness =1; + game->addObserver(NEW ATargetterPowerToughnessModifierUntilEOT(id, card, 1,2, NEW ManaCost(cost,1),tc)); + break; + } + case 2703: // Lost Order of Jarkeld + { + game->addObserver(NEW ALostOrderofJarkeld(_id, card)); + break; + } + default: + break; + } + + if (card->basicAbilities[LIFELINK]){ + ALifeLink * ability = NEW ALifeLink(_id, card); + game->addObserver(ability); + } + + for (int i=PROTECTIONGREEN; i <= PROTECTIONWHITE; i++){ + if (card->basicAbilities[i]){ + game->addObserver(NEW AProtectionFrom(_id, card, card, i - PROTECTIONGREEN + MTG_COLOR_GREEN)); + } + } + + if (card->basicAbilities[EXALTED]){ + game->addObserver(NEW AExalted(_id, card)); + } + + // Tested works the first r10 did not function because of the mistake in the array of the definition + if (card->basicAbilities[FORESTHOME]){ + game->addObserver(NEW AStrongLandLinkCreature(_id, card, "forest")); + } + if (card->basicAbilities[ISLANDHOME]){ + game->addObserver(NEW AStrongLandLinkCreature(_id, card, "island")); + } + if (card->basicAbilities[MOUNTAINHOME]){ + game->addObserver(NEW AStrongLandLinkCreature(_id, card,"moutain")); + } + if (card->basicAbilities[SWAMPHOME]){ + game->addObserver(NEW AStrongLandLinkCreature(_id, card,"swamp")); + } + if (card->basicAbilities[PLAINSHOME]){ + game->addObserver(NEW AStrongLandLinkCreature(_id, card,"plains")); + } + // New Abilities Flanking and Rampage + + if (card->basicAbilities [RAMPAGE1]){ + game->addObserver (NEW ARampageAbility(_id, card, 1, 1)); + } + + //Instants are put in the graveyard automatically if that's not already done + if (!putSourceInGraveyard){ + if (card->hasType("instant") || card->hasType("sorcery")){ + putSourceInGraveyard = 1; + } + } + if (putSourceInGraveyard == 1){ + MTGPlayerCards * zones = card->controller()->game; + zones->putInGraveyard(card); + } +} + +MTGAbility::MTGAbility(int id, MTGCardInstance * card):ActionElement(id){ + game = GameObserver::GetInstance();; + source = card; + target = card; +} + +MTGAbility::MTGAbility(int id, MTGCardInstance * _source,Damageable * _target ):ActionElement(id){ + game = GameObserver::GetInstance();; + source = _source; + target = _target; +} + +MTGAbility::~MTGAbility(){ + +} + +//returns 1 if this ability needs to be removed from the list of active abilities +int MTGAbility::testDestroy(){ + if (!game->isInPlay(source)){ + return 1; + } + if (target && !game->isInPlay((MTGCardInstance *)target)){ + source->controller()->game->putInGraveyard(source);//TODO put this in a better place ??? + return 1; + } + return 0; +} + + + +int MTGAbility::fireAbility(){ + game->mLayers->stackLayer()->addAbility(this); + return 1; +} + +// + +ActivatedAbility::ActivatedAbility(int id, MTGCardInstance * card, ManaCost * _cost, int _playerturnonly,int tap):MTGAbility(id,card), cost(_cost), playerturnonly(_playerturnonly), needsTapping(tap){ +} + + +int ActivatedAbility::isReactingToClick(MTGCardInstance * card){ + Player * player = game->currentPlayer; + if (!playerturnonly) player = game->currentlyActing(); + if (card == source && (!cost || player->getManaPool()->canAfford(cost)) && source->controller()==player && (!needsTapping || (!source->isTapped() && !source->hasSummoningSickness())) && player==game->currentlyActing()) + return 1; + return 0; +} + +int ActivatedAbility::reactToClick(MTGCardInstance * card){ + if (!isReactingToClick(card)) return 0; + if (needsTapping) source->tapped = 1; + if (cost) game->currentlyActing()->getManaPool()->pay(cost); + fireAbility(); + return 1; + +} + +int ActivatedAbility::reactToTargetClick(Targetable * object){ + if (!isReactingToTargetClick(object)) return 0; + if (needsTapping) source->tapped = 1; + if (cost) game->currentlyActing()->getManaPool()->pay(cost); + fireAbility(); + return 1; + +} + + +ActivatedAbility::~ActivatedAbility(){ + if (cost) delete cost; +} + +// + +TargetAbility::TargetAbility(int id, MTGCardInstance * card, TargetChooser * _tc,ManaCost * _cost, int _playerturnonly,int tap):ActivatedAbility(id, card,_cost,_playerturnonly, tap){ + tc = _tc; +} + +TargetAbility::TargetAbility(int id, MTGCardInstance * card,ManaCost * _cost, int _playerturnonly,int tap):ActivatedAbility(id, card,_cost,_playerturnonly, tap){ + tc = NULL; +} + +void TargetAbility::Update(float dt){ + JGE * mEngine = JGE::GetInstance(); + if (waitingForAnswer){ + if(mEngine->GetButtonClick(PSP_CTRL_CROSS)){ + waitingForAnswer = 0; + }else if(tc->targetsReadyCheck() == TARGET_OK_FULL){ + waitingForAnswer = 0; + ActivatedAbility::reactToClick(source); + } + } +} + +int TargetAbility::reactToTargetClick(Targetable * object){ + if (object->typeAsTarget() == TARGET_CARD) return reactToClick((MTGCardInstance *)object); + if (waitingForAnswer){ + tc->toggleTarget(object); + return 1; + } + return 0; +} + + +int TargetAbility::reactToClick(MTGCardInstance * card){ + if (!waitingForAnswer) { + if (isReactingToClick(card)){ + waitingForAnswer = 1; + tc->initTargets(); + } + }else{ + if (card == source){ + if (tc->targetsReadyCheck() == TARGET_OK){ + waitingForAnswer = 0; + ActivatedAbility::reactToClick(source); + } + }else{ + tc->toggleTarget(card); + } + } + return 1; +} + +void TargetAbility::Render(){ + //TODO +} + + +// + + +TriggeredAbility::TriggeredAbility(int id, MTGCardInstance * card, Damageable * _target):MTGAbility(id,card, _target){ +} + + +TriggeredAbility::TriggeredAbility(int id, MTGCardInstance * card):MTGAbility(id,card){ +} + +void TriggeredAbility::Update(float dt){ + if (trigger()) fireAbility(); +} + + + +// +InstantAbility::InstantAbility(int _id, MTGCardInstance * source):MTGAbility(_id, source){ + init = 0; + for (int i = 0; i < 2; i++){ + if(game->players[i]->game->inPlay->hasCard(source)){ + game->players[i]->game->putInGraveyard(source); + } + } +} + +void InstantAbility::Update(float dt){ + if (!init){ + init = resolve(); + } +} + +InstantAbility::InstantAbility(int _id, MTGCardInstance * source, Damageable * _target):MTGAbility(_id, source, _target){ + init = 0; + for (int i = 0; i < 2; i++){ + if(game->players[i]->game->inPlay->hasCard(source)){ + game->players[i]->game->putInGraveyard(source); + } + } +} + + + +//Instant abilities last generally until the end of the turn +int InstantAbility::testDestroy(){ + int newPhase = game->getCurrentGamePhase(); + if (newPhase != currentPhase && newPhase == MTG_PHASE_UNTAP) return 1; + currentPhase = newPhase; + return 0; + +} + + +void ListMaintainerAbility::Update(float dt){ + map::iterator it=cards.begin(); + while(it != cards.end()){ + MTGCardInstance * card = (*it).first; + it++; + int doDelete = 1; + for (int i = 0; i < 2; i++){ + Player * p = game->players[i]; + MTGGameZone * zones[] = {p->game->inPlay}; + for (int k = 0; k < 1; k++){ + MTGGameZone * zone = zones[k]; + if (zone->hasCard(card)){ + doDelete = 0; + break; + } + } + } + if (doDelete || !canBeInList(card)){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("DELETE FRO LISTMAINTAINER\n"); +#endif + cards.erase(card); + removed(card); + } + } + for (int i = 0; i < 2; i++){ + Player * p = game->players[i]; + MTGGameZone * zones[] = {p->game->inPlay}; + for (int k = 0; k < 1; k++){ + MTGGameZone * zone = zones[k]; + for (int j = 0; j < zone->nb_cards; j++){ + if (canBeInList(zone->cards[j])){ + if(cards.find(zone->cards[j]) == cards.end()){ + cards[zone->cards[j]] = true; + added(zone->cards[j]); + } + } + } + } + } +} + +//Destroy the spell -> remove all targets +int ListMaintainerAbility::destroy(){ + map::iterator it; + + for ( it=cards.begin() ; it != cards.end(); it++ ){ + removed((*it).first); + } + cards.clear(); + return 1; +} diff --git a/projects/mtg/src/MTGCard.cpp b/projects/mtg/src/MTGCard.cpp index 57a3b7ed7..bb8dde6f3 100644 --- a/projects/mtg/src/MTGCard.cpp +++ b/projects/mtg/src/MTGCard.cpp @@ -1,310 +1,310 @@ -//------------------------------------------------------ -//MTGCard Class -//------------------------------------------------- -//TODO Fill BasicAbilities - -#include "../include/debug.h" -#include "../include/MTGCard.h" - -#include "../include/TexturesCache.h" -#include "../include/Subtypes.h" - -#include -#include -using std::string; - - -const char * const MTGCard::Colors_To_Text[] = {"Artifact", "Green", "Blue", "Red", "Black", "White", "Land"}; - -MTGCard::MTGCard(){ - init(); - mCache = NULL; -} - -MTGCard::MTGCard(TexturesCache * cache, int set_id){ - init(); - mCache = cache; - setId = set_id; -} - -const char * MTGCard::getSetName(){ - return MtgSets::SetsList->values[setId].c_str(); -} - -MTGCard::MTGCard(MTGCard * source){ - mCache = source->mCache; - for (int i = 0; i< NB_BASIC_ABILITIES; i++){ - basicAbilities[i] = source->basicAbilities[i]; - } - for (int i = 0; i< MAX_TYPES_PER_CARD; i++){ - types[i] = source->types[i]; - } - nb_types = source->nb_types; - for (int i = 0; i< MTG_NB_COLORS; i++){ - colors[i] = source->colors[i]; - } - manaCost.copy(source->getManaCost()); - - text = source->text; - name = source->name; - strcpy(image_name, source->image_name); - - rarity = source->rarity; - power = source->power; - toughness = source->toughness; - mtgid = source->mtgid; - setId = source->setId; - formattedTextInit = 0; - magicText = source->magicText; - spellTargetType = source->spellTargetType; - alias = source->alias; -} - -int MTGCard::init(){ - nb_types = 0; - for (int i = 0; i< NB_BASIC_ABILITIES; i++){ - basicAbilities[i] = 0; - } - for (int i = 0; i< MAX_TYPES_PER_CARD; i++){ - types[i] = 0; - } - for (int i = 0; i< MTG_NB_COLORS; i++){ - colors[i] = 0; - } - setId = 0; - formattedTextInit = 0; - magicText = ""; - spellTargetType = ""; - alias = 0; - return 1; -} - -JQuad * MTGCard::getQuad(int type){ - if (mCache == NULL){ - return NULL; - } - return mCache->getQuad(this, type); -} - - -JQuad * MTGCard::getThumb(){ - return getQuad(CACHE_THUMB); -} - -JQuad * MTGCard::getQuad(TexturesCache * cache){ - - return cache->getQuad(this); -} - - - -int MTGCard::isACreature(){ - return (hasSubtype("creature")); -} - -void MTGCard::setColor(int _color, int removeAllOthers){ - if (removeAllOthers){ - for (int i=0; i=0 && color <=5){ - return Colors_To_Text[color]; - } - return "Unknown"; -} - - -void MTGCard::setMTGId(int id){ - mtgid = id; - sprintf(image_name, "%d.jpg", mtgid); -} - -int MTGCard::getMTGId(){ - return mtgid; -} -int MTGCard::getId(){ - return mtgid; -} - -char MTGCard::getRarity(){ - return rarity; -} - -void MTGCard::setRarity(char _rarity){ - rarity = _rarity; -} - -void MTGCard::setType(const char * _type_text){ - setSubtype(_type_text); -} - -void MTGCard::addType(char * _type_text){ - setSubtype(_type_text); -} - -void MTGCard::setSubtype( string value){ - string s = value; - while (s.size()){ - unsigned int found = s.find(" "); - if (found != string::npos){ - int id = Subtypes::subtypesList->Add(s.substr(0,found)); - addType(id); - s = s.substr(found+1); - }else{ - int id = Subtypes::subtypesList->Add(s); - addType(id); - s = ""; - } - } -} - -void MTGCard::addType(int id){ - types[nb_types] = id; - nb_types++; -} - - -//Removes a type from the types of a given card -//If removeAll is true, removes all occurences of this type, otherwise only removes the first occurence -int MTGCard::removeType(string value, int removeAll){ - - int id = Subtypes::subtypesList->Add(value); - return removeType(id, removeAll); -} - -int MTGCard::removeType(int id, int removeAll){ - int result = 0; - for (int i = nb_types -1 ; i >=0; i--){ - if (types[i] == id){ - types[i] = types[nb_types -1]; - nb_types--; - result++; - if (!removeAll) return result; - } - } - return result; -} - - -char * MTGCard::getImageName(){ - return image_name; -} - - -void MTGCard::setText( string value){ - text = value; -} - -const char * MTGCard::getText(){ - return text.c_str(); -} - -void MTGCard::addMagicText(string value){ - std::transform( value.begin(), value.end(), value.begin(),::tolower ); - if (magicText.size()) magicText.append("\n"); - magicText.append(value); -} - -void MTGCard::setName( string value){ - name = value; -} - -const char * MTGCard::getName(){ - return name.c_str(); -} - - -ManaCost * MTGCard::getManaCost(){ - return &manaCost; -} - - - -int MTGCard::hasType(int _type){ - int i; - - - for (i = 0; iAdd(_type); - return(hasType(id)); -} - - -int MTGCard::hasSubtype(const char * _subtype){ - int id = Subtypes::subtypesList->Add(_subtype); - return(hasType(id)); -} - -int MTGCard::hasSubtype(string _subtype){ - int id = Subtypes::subtypesList->Add(_subtype); - return(hasType(id)); -} - - -int MTGCard::has(int basicAbility){ - return basicAbilities[basicAbility]; -} - -//--------------------------------------------- -// Creature specific -//--------------------------------------------- -void MTGCard::setPower(int _power){ - power = _power; -} - -int MTGCard::getPower(){ - return power; -} - -void MTGCard::setToughness(int _toughness){ - toughness = _toughness; -} - -int MTGCard::getToughness(){ - return toughness; -} +//------------------------------------------------------ +//MTGCard Class +//------------------------------------------------- +//TODO Fill BasicAbilities + +#include "../include/debug.h" +#include "../include/MTGCard.h" + +#include "../include/TexturesCache.h" +#include "../include/Subtypes.h" + +#include +#include +using std::string; + + +const char * const MTGCard::Colors_To_Text[] = {"Artifact", "Green", "Blue", "Red", "Black", "White", "Land"}; + +MTGCard::MTGCard(){ + init(); + mCache = NULL; +} + +MTGCard::MTGCard(TexturesCache * cache, int set_id){ + init(); + mCache = cache; + setId = set_id; +} + +const char * MTGCard::getSetName(){ + return MtgSets::SetsList->values[setId].c_str(); +} + +MTGCard::MTGCard(MTGCard * source){ + mCache = source->mCache; + for (int i = 0; i< NB_BASIC_ABILITIES; i++){ + basicAbilities[i] = source->basicAbilities[i]; + } + for (int i = 0; i< MAX_TYPES_PER_CARD; i++){ + types[i] = source->types[i]; + } + nb_types = source->nb_types; + for (int i = 0; i< MTG_NB_COLORS; i++){ + colors[i] = source->colors[i]; + } + manaCost.copy(source->getManaCost()); + + text = source->text; + name = source->name; + strcpy(image_name, source->image_name); + + rarity = source->rarity; + power = source->power; + toughness = source->toughness; + mtgid = source->mtgid; + setId = source->setId; + formattedTextInit = 0; + magicText = source->magicText; + spellTargetType = source->spellTargetType; + alias = source->alias; +} + +int MTGCard::init(){ + nb_types = 0; + for (int i = 0; i< NB_BASIC_ABILITIES; i++){ + basicAbilities[i] = 0; + } + for (int i = 0; i< MAX_TYPES_PER_CARD; i++){ + types[i] = 0; + } + for (int i = 0; i< MTG_NB_COLORS; i++){ + colors[i] = 0; + } + setId = 0; + formattedTextInit = 0; + magicText = ""; + spellTargetType = ""; + alias = 0; + return 1; +} + +JQuad * MTGCard::getQuad(int type){ + if (mCache == NULL){ + return NULL; + } + return mCache->getQuad(this, type); +} + + +JQuad * MTGCard::getThumb(){ + return getQuad(CACHE_THUMB); +} + +JQuad * MTGCard::getQuad(TexturesCache * cache){ + + return cache->getQuad(this); +} + + + +int MTGCard::isACreature(){ + return (hasSubtype("creature")); +} + +void MTGCard::setColor(int _color, int removeAllOthers){ + if (removeAllOthers){ + for (int i=0; i=0 && color <=5){ + return Colors_To_Text[color]; + } + return "Unknown"; +} + + +void MTGCard::setMTGId(int id){ + mtgid = id; + sprintf(image_name, "%d.jpg", mtgid); +} + +int MTGCard::getMTGId(){ + return mtgid; +} +int MTGCard::getId(){ + return mtgid; +} + +char MTGCard::getRarity(){ + return rarity; +} + +void MTGCard::setRarity(char _rarity){ + rarity = _rarity; +} + +void MTGCard::setType(const char * _type_text){ + setSubtype(_type_text); +} + +void MTGCard::addType(char * _type_text){ + setSubtype(_type_text); +} + +void MTGCard::setSubtype( string value){ + string s = value; + while (s.size()){ + unsigned int found = s.find(" "); + if (found != string::npos){ + int id = Subtypes::subtypesList->Add(s.substr(0,found)); + addType(id); + s = s.substr(found+1); + }else{ + int id = Subtypes::subtypesList->Add(s); + addType(id); + s = ""; + } + } +} + +void MTGCard::addType(int id){ + types[nb_types] = id; + nb_types++; +} + + +//Removes a type from the types of a given card +//If removeAll is true, removes all occurences of this type, otherwise only removes the first occurence +int MTGCard::removeType(string value, int removeAll){ + + int id = Subtypes::subtypesList->Add(value); + return removeType(id, removeAll); +} + +int MTGCard::removeType(int id, int removeAll){ + int result = 0; + for (int i = nb_types -1 ; i >=0; i--){ + if (types[i] == id){ + types[i] = types[nb_types -1]; + nb_types--; + result++; + if (!removeAll) return result; + } + } + return result; +} + + +char * MTGCard::getImageName(){ + return image_name; +} + + +void MTGCard::setText( string value){ + text = value; +} + +const char * MTGCard::getText(){ + return text.c_str(); +} + +void MTGCard::addMagicText(string value){ + std::transform( value.begin(), value.end(), value.begin(),::tolower ); + if (magicText.size()) magicText.append("\n"); + magicText.append(value); +} + +void MTGCard::setName( string value){ + name = value; +} + +const char * MTGCard::getName(){ + return name.c_str(); +} + + +ManaCost * MTGCard::getManaCost(){ + return &manaCost; +} + + + +int MTGCard::hasType(int _type){ + int i; + + + for (i = 0; iAdd(_type); + return(hasType(id)); +} + + +int MTGCard::hasSubtype(const char * _subtype){ + int id = Subtypes::subtypesList->Add(_subtype); + return(hasType(id)); +} + +int MTGCard::hasSubtype(string _subtype){ + int id = Subtypes::subtypesList->Add(_subtype); + return(hasType(id)); +} + + +int MTGCard::has(int basicAbility){ + return basicAbilities[basicAbility]; +} + +//--------------------------------------------- +// Creature specific +//--------------------------------------------- +void MTGCard::setPower(int _power){ + power = _power; +} + +int MTGCard::getPower(){ + return power; +} + +void MTGCard::setToughness(int _toughness){ + toughness = _toughness; +} + +int MTGCard::getToughness(){ + return toughness; +} diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index 1a2b66cb7..e5ce5695b 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -1,407 +1,407 @@ -/*--------------------------------------------- -Card Instance -Instance of a given MTGCard in the game -Although there is only one MTGCard of each type, there can be as much Instances of it as needed in the game --------------------------------------------- -*/ -#include "../include/debug.h" -#include "../include/MTGCardInstance.h" -#include "../include/CardDescriptor.h" -#include "../include/Counters.h" - -MTGCardInstance::MTGCardInstance(): MTGCard(), Damageable(0){ - LOG("==Creating MTGCardInstance=="); -initMTGCI(); -LOG("==Creating MTGCardInstance Successful=="); -} -MTGCardInstance::MTGCardInstance(MTGCard * card, MTGPlayerCards * _belongs_to): MTGCard(card), Damageable(card->getToughness()){ - LOG("==Creating MTGCardInstance=="); - initMTGCI(); - model = card; - lifeOrig = life; - belongs_to=_belongs_to; - initAttackersDefensers(); - life=toughness; - LOG("==Creating MTGCardInstance Successful=="); - -} - -MTGCardInstance::~MTGCardInstance(){ - LOG("==Deleting MTGCardInstance=="); - SAFE_DELETE(blockers); - SAFE_DELETE(counters); - LOG("==Deleting MTGCardInstance Succesfull=="); -} -void MTGCardInstance::initMTGCI(){ - model=NULL; - lifeOrig = 0; - doDamageTest = 0; - belongs_to=NULL; - tapped = 0; - blockers = NEW Blockers(); - untapping = 0; - summoningSickness = 0; - target = NULL; - nbprotections = 0; - type_as_damageable = DAMAGEABLE_MTGCARDINSTANCE; - banding = NULL; - owner = NULL; - changedZoneRecently = 0; - counters = NEW Counters(this); -} - - -void MTGCardInstance::addType(int type){ - types[nb_types] = type; - nb_types++; -} - -Blockers * MTGCardInstance::getBlockers(){ - return blockers; -} - -int MTGCardInstance::isInPlay(){ - GameObserver * game = GameObserver::GetInstance(); - for (int i = 0 ; i < 2 ; i++){ - MTGGameZone * zone = game->players[i]->game->inPlay; - if (zone->hasCard(this)) return 1; - } - return 0; -} - -int MTGCardInstance::afterDamage(){ - if (!doDamageTest) return 0; - #if defined (WIN32) || defined (LINUX) -char buf[4096], *p = buf; -sprintf(buf,"After Damage Test, life is %i for %s \n",life,model->getName()); -OutputDebugString(buf); -#endif - doDamageTest = 0; - if (life <=0 && isInPlay()){ - GameObserver * game = GameObserver::GetInstance(); - game->mLayers->stackLayer()->addPutInGraveyard(this); - return 1; - } - return 0; -} - - -MTGGameZone * MTGCardInstance::getCurrentZone(){ - GameObserver * game = GameObserver::GetInstance(); - for (int i = 0; i < 2; i++){ - MTGPlayerCards * g = game->players[i]->game; - MTGGameZone * zones[] = {g->inPlay,g->graveyard,g->hand, g->library}; - for (int k = 0; k < 4; k++){ - MTGGameZone * zone = zones[k]; - if (zone->hasCard(this)) return zone; - } - } - return NULL; -} - -JQuad * MTGCardInstance::getIcon(){ - return getThumb(); -} - -int MTGCardInstance::has(int basicAbility){ - return basicAbilities[basicAbility]; -} - - - - - -//Taps the card -void MTGCardInstance::tap(){ - tapped = 1; -} - -void MTGCardInstance::setUntapping(){ - untapping = 1; -} - -int MTGCardInstance::isUntapping(){ - return untapping; -} - -//Untaps the card -void MTGCardInstance::untap(){ - if (untapping){ - tapped = 0; - untapping = 0; - } -} - -//Tells if the card is tapped or not -int MTGCardInstance::isTapped(){ - return tapped; -} - -void MTGCardInstance::resetAllDamage(){ - //for (int i=0;icurrentPlayer == controller()) summoningSickness = 0; - return 1; -} - -/* Summoning Sickness - * 212.3f A creaturefs activated ability with the tap symbol or the untap symbol in its activation cost - * canft be played unless the creature has been under its controllerfs control since the start of his or - * her most recent turn. A creature canft attack unless it has been under its controllerfs control - * since the start of his or her most recent turn. This rule is informally called the gsummoning - * sicknessh rule. Ignore this rule for creatures with haste (see rule 502.5). - */ -int MTGCardInstance::hasSummoningSickness(){ - if (!summoningSickness) return 0; - if (basicAbilities[HASTE]) return 0; - if (!isACreature()) return 0; - return 1; -} - -int MTGCardInstance::changeController(Player * newController){ - Player * originalOwner = controller(); - if (originalOwner == newController) return 0; - originalOwner->game->inPlay->removeCard(this); - newController->game->inPlay->addCard(this); - summoningSickness = 1; - return 1; -} - -//Reset the card parameters -int MTGCardInstance::reset(){ - cleanup(); - tapped=0; - SAFE_DELETE(counters); - counters = NEW Counters(this); - return 1; -} - -Player * MTGCardInstance::controller(){ - GameObserver * game = GameObserver::GetInstance(); - if (!game) return NULL; - for (int i = 0; i < 2; i++){ - if (game->players[i]->game->inPlay->hasCard(this)) return game->players[i]; - if (game->players[i]->game->stack->hasCard(this)) return game->players[i]; - if (game->players[i]->game->graveyard->hasCard(this)) return game->players[i]; - } - return NULL; -} - -int MTGCardInstance::canAttack(){ - if (!hasSummoningSickness() && !tapped && isACreature() && basicAbilities[DEFENSER] !=1) - return 1; - return 0; -} - - -int MTGCardInstance::addToToughness(int value){ - toughness+=value; - life+=value; - doDamageTest = 1; - return 1; -} - -int MTGCardInstance::setToughness(int value){ - toughness=value; - life=value; - doDamageTest = 1; - return 1; -} - -int MTGCardInstance::canBlock(){ - if (!tapped && isACreature())return 1; - return 0; -} - -int MTGCardInstance::canBlock(MTGCardInstance * opponent){ - if (!canBlock()) return 0; - if (!opponent) return 1; - if (!opponent->isAttacker()) return 0; - // Comprehensive rule 502.7f : If a creature with protection attacks, it can't be blocked by creatures that have the stated quality. - if (opponent->protectedAgainst(this)) return 0; - if (opponent->basicAbilities[UNBLOCKABLE]) return 0; - if (opponent->basicAbilities[FEAR] && !(hasColor(MTG_COLOR_ARTIFACT) || hasColor(MTG_COLOR_BLACK))) return 0; - if (opponent->basicAbilities[FLYING] && !( basicAbilities[FLYING] || basicAbilities[REACH])) return 0; - // If opponent has shadow and a creature does not have either shadow or reachshadow it cannot be blocked - if (opponent->basicAbilities[SHADOW] && !( basicAbilities[SHADOW] || basicAbilities[REACHSHADOW])) return 0; - // If opponent does not have shadow and a creature has shadow it cannot be blocked - if (!opponent->basicAbilities[SHADOW] && basicAbilities[SHADOW]) return 0; - if (opponent->basicAbilities[SWAMPWALK] && controller()->game->inPlay->hasType("swamp")) return 0; - if (opponent->basicAbilities[FORESTWALK] && controller()->game->inPlay->hasType("forest")) return 0; - if (opponent->basicAbilities[ISLANDWALK] && controller()->game->inPlay->hasType("island")) return 0; - if (opponent->basicAbilities[MOUNTAINWALK] && controller()->game->inPlay->hasType("mountain")) return 0; - if (opponent->basicAbilities[PLAINSWALK] && controller()->game->inPlay->hasType("plains")) return 0; - return 1; -} - -MTGCardInstance * MTGCardInstance::getNextPartner(){ - MTGInPlay * inplay = controller()->game->inPlay; - MTGCardInstance * bandingPartner = inplay->getNextAttacker(banding); - while (bandingPartner){ - if (basicAbilities[BANDING] || bandingPartner->basicAbilities[BANDING]) return bandingPartner; - bandingPartner = inplay->getNextAttacker(bandingPartner); - } - return NULL; -} - -void MTGCardInstance::unband(){ - if (!banding) return; - - MTGCardInstance * _banding = banding; - banding = NULL; - MTGCardInstance * newbanding = NULL; - MTGInPlay * inplay = controller()->game->inPlay; - int nbpartners = inplay->nbPartners(this); - MTGCardInstance * card = inplay->getNextAttacker(NULL); - while(card){ - if (card != this){ - if (card->banding == _banding){ - if (nbpartners == 1){ - card->banding = NULL; - return; - }else{ - if (!newbanding) newbanding = card; - card->banding = newbanding; - } - } - } - card = inplay->getNextAttacker(card); - } - return ; -} - -int MTGCardInstance::toggleAttacker(){ - //TODO more controls ? - if (canAttack()){ - if (!attacker){ - attacker = 1; - tapped = 1; - return 1; - }else{ - MTGCardInstance * bandingPartner = getNextPartner(); - if (bandingPartner){ - if (banding) unband(); - if (!bandingPartner->banding) bandingPartner->banding = bandingPartner; - banding = bandingPartner->banding; - return 1; - }else{ - attacker = 0; - tapped = 0; - return 1; - } - } - } - return 0; -} - -int MTGCardInstance::isAttacker(){ - return attacker; -} - -MTGCardInstance * MTGCardInstance::isDefenser(){ - return defenser; -} - - -int MTGCardInstance::nbOpponents(){ - int result= 0; - MTGCardInstance* opponent = getNextOpponent(); - while (opponent){ - result++; - opponent = getNextOpponent(opponent); - } - return result; -} -//Returns opponents to this card for this turn. This * should * take into account banding -MTGCardInstance * MTGCardInstance::getNextOpponent(MTGCardInstance * previous){ - GameObserver * game = GameObserver::GetInstance(); - int foundprevious = 0; - if (!previous) foundprevious = 1; - if (attacker && game->currentPlayer->game->inPlay->hasCard(this)){ - MTGInPlay * inPlay = game->opponent()->game->inPlay; - for (int i = 0; i < inPlay->nb_cards; i ++){ - MTGCardInstance * current = inPlay->cards[i]; - if (current == previous){ - foundprevious = 1; - }else if (foundprevious){ - MTGCardInstance * defensersOpponent = current->isDefenser(); - if (defensersOpponent && (defensersOpponent == this || (banding && defensersOpponent->banding == banding))){ - return current; - } - } - } - }else if (defenser && game->opponent()->game->inPlay->hasCard(this)){ - MTGInPlay * inPlay = game->currentPlayer->game->inPlay; - for (int i = 0; i < inPlay->nb_cards; i ++){ - MTGCardInstance * current = inPlay->cards[i]; - if (current == previous){ - foundprevious = 1; - }else if (foundprevious){ - if (defenser == current || (current->banding && defenser->banding == current->banding)){ - return current; - } - } - } - } - return NULL; -} - -int MTGCardInstance::toggleDefenser(MTGCardInstance * opponent){ - if (canBlock()){ - if (canBlock(opponent)){ - defenser = opponent; - return 1; - } - } - return 0; -} - - -int MTGCardInstance::addProtection(CardDescriptor * cd){ - protections[nbprotections] = cd; - nbprotections++; - return nbprotections; -} - -int MTGCardInstance::removeProtection(CardDescriptor * cd, int erase){ - for (int i = 0; i < nbprotections ; i++){ - if (protections[i] == cd){ - if (erase) delete (protections[i]); - protections[i] = protections[nbprotections -1]; - protections[nbprotections -1] = NULL; - nbprotections--; - return 1; - } - } - return 0; -} - -int MTGCardInstance::protectedAgainst(MTGCardInstance * card){ - for (int i = 0; i < nbprotections ; i++){ - if (protections[i]->match(card)) return 1; - } - return 0; -} +/*--------------------------------------------- + Card Instance + Instance of a given MTGCard in the game + Although there is only one MTGCard of each type, there can be as much Instances of it as needed in the game + -------------------------------------------- +*/ +#include "../include/debug.h" +#include "../include/MTGCardInstance.h" +#include "../include/CardDescriptor.h" +#include "../include/Counters.h" + +MTGCardInstance::MTGCardInstance(): MTGCard(), Damageable(0){ + LOG("==Creating MTGCardInstance=="); + initMTGCI(); + LOG("==Creating MTGCardInstance Successful=="); +} +MTGCardInstance::MTGCardInstance(MTGCard * card, MTGPlayerCards * _belongs_to): MTGCard(card), Damageable(card->getToughness()){ + LOG("==Creating MTGCardInstance=="); + initMTGCI(); + model = card; + lifeOrig = life; + belongs_to=_belongs_to; + initAttackersDefensers(); + life=toughness; + LOG("==Creating MTGCardInstance Successful=="); + +} + +MTGCardInstance::~MTGCardInstance(){ + LOG("==Deleting MTGCardInstance=="); + SAFE_DELETE(blockers); + SAFE_DELETE(counters); + LOG("==Deleting MTGCardInstance Succesfull=="); +} +void MTGCardInstance::initMTGCI(){ + model=NULL; + lifeOrig = 0; + doDamageTest = 0; + belongs_to=NULL; + tapped = 0; + blockers = NEW Blockers(); + untapping = 0; + summoningSickness = 0; + target = NULL; + nbprotections = 0; + type_as_damageable = DAMAGEABLE_MTGCARDINSTANCE; + banding = NULL; + owner = NULL; + changedZoneRecently = 0; + counters = NEW Counters(this); +} + + +void MTGCardInstance::addType(int type){ + types[nb_types] = type; + nb_types++; +} + +Blockers * MTGCardInstance::getBlockers(){ + return blockers; +} + +int MTGCardInstance::isInPlay(){ + GameObserver * game = GameObserver::GetInstance(); + for (int i = 0 ; i < 2 ; i++){ + MTGGameZone * zone = game->players[i]->game->inPlay; + if (zone->hasCard(this)) return 1; + } + return 0; +} + +int MTGCardInstance::afterDamage(){ + if (!doDamageTest) return 0; +#if defined (WIN32) || defined (LINUX) + char buf[4096], *p = buf; + sprintf(buf,"After Damage Test, life is %i for %s \n",life,model->getName()); + OutputDebugString(buf); +#endif + doDamageTest = 0; + if (life <=0 && isInPlay()){ + GameObserver * game = GameObserver::GetInstance(); + game->mLayers->stackLayer()->addPutInGraveyard(this); + return 1; + } + return 0; +} + + +MTGGameZone * MTGCardInstance::getCurrentZone(){ + GameObserver * game = GameObserver::GetInstance(); + for (int i = 0; i < 2; i++){ + MTGPlayerCards * g = game->players[i]->game; + MTGGameZone * zones[] = {g->inPlay,g->graveyard,g->hand, g->library}; + for (int k = 0; k < 4; k++){ + MTGGameZone * zone = zones[k]; + if (zone->hasCard(this)) return zone; + } + } + return NULL; +} + +JQuad * MTGCardInstance::getIcon(){ + return getThumb(); +} + +int MTGCardInstance::has(int basicAbility){ + return basicAbilities[basicAbility]; +} + + + + + +//Taps the card +void MTGCardInstance::tap(){ + tapped = 1; +} + +void MTGCardInstance::setUntapping(){ + untapping = 1; +} + +int MTGCardInstance::isUntapping(){ + return untapping; +} + +//Untaps the card +void MTGCardInstance::untap(){ + if (untapping){ + tapped = 0; + untapping = 0; + } +} + +//Tells if the card is tapped or not +int MTGCardInstance::isTapped(){ + return tapped; +} + +void MTGCardInstance::resetAllDamage(){ + //for (int i=0;icurrentPlayer == controller()) summoningSickness = 0; + return 1; +} + +/* Summoning Sickness + * 212.3f A creaturefs activated ability with the tap symbol or the untap symbol in its activation cost + * canft be played unless the creature has been under its controllerfs control since the start of his or + * her most recent turn. A creature canft attack unless it has been under its controllerfs control + * since the start of his or her most recent turn. This rule is informally called the gsummoning + * sicknessh rule. Ignore this rule for creatures with haste (see rule 502.5). + */ +int MTGCardInstance::hasSummoningSickness(){ + if (!summoningSickness) return 0; + if (basicAbilities[HASTE]) return 0; + if (!isACreature()) return 0; + return 1; +} + +int MTGCardInstance::changeController(Player * newController){ + Player * originalOwner = controller(); + if (originalOwner == newController) return 0; + originalOwner->game->inPlay->removeCard(this); + newController->game->inPlay->addCard(this); + summoningSickness = 1; + return 1; +} + +//Reset the card parameters +int MTGCardInstance::reset(){ + cleanup(); + tapped=0; + SAFE_DELETE(counters); + counters = NEW Counters(this); + return 1; +} + +Player * MTGCardInstance::controller(){ + GameObserver * game = GameObserver::GetInstance(); + if (!game) return NULL; + for (int i = 0; i < 2; i++){ + if (game->players[i]->game->inPlay->hasCard(this)) return game->players[i]; + if (game->players[i]->game->stack->hasCard(this)) return game->players[i]; + if (game->players[i]->game->graveyard->hasCard(this)) return game->players[i]; + } + return NULL; +} + +int MTGCardInstance::canAttack(){ + if (!hasSummoningSickness() && !tapped && isACreature() && basicAbilities[DEFENSER] !=1) + return 1; + return 0; +} + + +int MTGCardInstance::addToToughness(int value){ + toughness+=value; + life+=value; + doDamageTest = 1; + return 1; +} + +int MTGCardInstance::setToughness(int value){ + toughness=value; + life=value; + doDamageTest = 1; + return 1; +} + +int MTGCardInstance::canBlock(){ + if (!tapped && isACreature())return 1; + return 0; +} + +int MTGCardInstance::canBlock(MTGCardInstance * opponent){ + if (!canBlock()) return 0; + if (!opponent) return 1; + if (!opponent->isAttacker()) return 0; + // Comprehensive rule 502.7f : If a creature with protection attacks, it can't be blocked by creatures that have the stated quality. + if (opponent->protectedAgainst(this)) return 0; + if (opponent->basicAbilities[UNBLOCKABLE]) return 0; + if (opponent->basicAbilities[FEAR] && !(hasColor(MTG_COLOR_ARTIFACT) || hasColor(MTG_COLOR_BLACK))) return 0; + if (opponent->basicAbilities[FLYING] && !( basicAbilities[FLYING] || basicAbilities[REACH])) return 0; + // If opponent has shadow and a creature does not have either shadow or reachshadow it cannot be blocked + if (opponent->basicAbilities[SHADOW] && !( basicAbilities[SHADOW] || basicAbilities[REACHSHADOW])) return 0; + // If opponent does not have shadow and a creature has shadow it cannot be blocked + if (!opponent->basicAbilities[SHADOW] && basicAbilities[SHADOW]) return 0; + if (opponent->basicAbilities[SWAMPWALK] && controller()->game->inPlay->hasType("swamp")) return 0; + if (opponent->basicAbilities[FORESTWALK] && controller()->game->inPlay->hasType("forest")) return 0; + if (opponent->basicAbilities[ISLANDWALK] && controller()->game->inPlay->hasType("island")) return 0; + if (opponent->basicAbilities[MOUNTAINWALK] && controller()->game->inPlay->hasType("mountain")) return 0; + if (opponent->basicAbilities[PLAINSWALK] && controller()->game->inPlay->hasType("plains")) return 0; + return 1; +} + +MTGCardInstance * MTGCardInstance::getNextPartner(){ + MTGInPlay * inplay = controller()->game->inPlay; + MTGCardInstance * bandingPartner = inplay->getNextAttacker(banding); + while (bandingPartner){ + if (basicAbilities[BANDING] || bandingPartner->basicAbilities[BANDING]) return bandingPartner; + bandingPartner = inplay->getNextAttacker(bandingPartner); + } + return NULL; +} + +void MTGCardInstance::unband(){ + if (!banding) return; + + MTGCardInstance * _banding = banding; + banding = NULL; + MTGCardInstance * newbanding = NULL; + MTGInPlay * inplay = controller()->game->inPlay; + int nbpartners = inplay->nbPartners(this); + MTGCardInstance * card = inplay->getNextAttacker(NULL); + while(card){ + if (card != this){ + if (card->banding == _banding){ + if (nbpartners == 1){ + card->banding = NULL; + return; + }else{ + if (!newbanding) newbanding = card; + card->banding = newbanding; + } + } + } + card = inplay->getNextAttacker(card); + } + return ; +} + +int MTGCardInstance::toggleAttacker(){ + //TODO more controls ? + if (canAttack()){ + if (!attacker){ + attacker = 1; + tapped = 1; + return 1; + }else{ + MTGCardInstance * bandingPartner = getNextPartner(); + if (bandingPartner){ + if (banding) unband(); + if (!bandingPartner->banding) bandingPartner->banding = bandingPartner; + banding = bandingPartner->banding; + return 1; + }else{ + attacker = 0; + tapped = 0; + return 1; + } + } + } + return 0; +} + +int MTGCardInstance::isAttacker(){ + return attacker; +} + +MTGCardInstance * MTGCardInstance::isDefenser(){ + return defenser; +} + + +int MTGCardInstance::nbOpponents(){ + int result= 0; + MTGCardInstance* opponent = getNextOpponent(); + while (opponent){ + result++; + opponent = getNextOpponent(opponent); + } + return result; +} +//Returns opponents to this card for this turn. This * should * take into account banding +MTGCardInstance * MTGCardInstance::getNextOpponent(MTGCardInstance * previous){ + GameObserver * game = GameObserver::GetInstance(); + int foundprevious = 0; + if (!previous) foundprevious = 1; + if (attacker && game->currentPlayer->game->inPlay->hasCard(this)){ + MTGInPlay * inPlay = game->opponent()->game->inPlay; + for (int i = 0; i < inPlay->nb_cards; i ++){ + MTGCardInstance * current = inPlay->cards[i]; + if (current == previous){ + foundprevious = 1; + }else if (foundprevious){ + MTGCardInstance * defensersOpponent = current->isDefenser(); + if (defensersOpponent && (defensersOpponent == this || (banding && defensersOpponent->banding == banding))){ + return current; + } + } + } + }else if (defenser && game->opponent()->game->inPlay->hasCard(this)){ + MTGInPlay * inPlay = game->currentPlayer->game->inPlay; + for (int i = 0; i < inPlay->nb_cards; i ++){ + MTGCardInstance * current = inPlay->cards[i]; + if (current == previous){ + foundprevious = 1; + }else if (foundprevious){ + if (defenser == current || (current->banding && defenser->banding == current->banding)){ + return current; + } + } + } + } + return NULL; +} + +int MTGCardInstance::toggleDefenser(MTGCardInstance * opponent){ + if (canBlock()){ + if (canBlock(opponent)){ + defenser = opponent; + return 1; + } + } + return 0; +} + + +int MTGCardInstance::addProtection(CardDescriptor * cd){ + protections[nbprotections] = cd; + nbprotections++; + return nbprotections; +} + +int MTGCardInstance::removeProtection(CardDescriptor * cd, int erase){ + for (int i = 0; i < nbprotections ; i++){ + if (protections[i] == cd){ + if (erase) delete (protections[i]); + protections[i] = protections[nbprotections -1]; + protections[nbprotections -1] = NULL; + nbprotections--; + return 1; + } + } + return 0; +} + +int MTGCardInstance::protectedAgainst(MTGCardInstance * card){ + for (int i = 0; i < nbprotections ; i++){ + if (protections[i]->match(card)) return 1; + } + return 0; +} diff --git a/projects/mtg/src/MTGDeck.cpp b/projects/mtg/src/MTGDeck.cpp index 88de571f8..6b5b525fa 100644 --- a/projects/mtg/src/MTGDeck.cpp +++ b/projects/mtg/src/MTGDeck.cpp @@ -1,385 +1,385 @@ -#include "../include/debug.h" -#include "../include/MTGDeck.h" -#include "../include/utils.h" -#include -#include -using std::string; - -#include - -#if defined (WIN32) || defined (LINUX) -#include -#endif - - - - - -MtgSets * MtgSets::SetsList = NEW MtgSets(); - - - -MtgSets::MtgSets(){ - nb_items = 0; -} - -int MtgSets::Add(const char * name){ - string value = name; - values[nb_items] = value; - nb_items++; - return nb_items - 1; -} - - -int MTGAllCards::processConfLine(char *buffer, MTGCard *card){ - string s = buffer; - unsigned int i = s.find_first_of("="); - if (i == string::npos) return 0; - string key = s.substr(0,i); - string value = s.substr(i+1); - - if(key.compare( "auto")==0){ - card->addMagicText(value); - } - else if(key.compare( "alias")==0){ - card->alias=atoi(value.c_str()); - } - else if(key.compare( "target")==0){ - std::transform( value.begin(), value.end(), value.begin(),::tolower ); - card->spellTargetType=value; - } - else if(key.compare( "text")==0){ - card->setText(value); - }else if (key.compare("abilities")==0){ - //Specific Abilities - std::transform( value.begin(), value.end(), value.begin(),::tolower ); - for (int j = 0; j < NB_BASIC_ABILITIES; j++){ - unsigned int found = value.find(MTGBasicAbilities[j]); - if (found != string::npos){ - card->basicAbilities[j] = 1; - } - } - }else if(key.compare("id")==0){ - card->setMTGId(atoi(value.c_str())); - }else if(key.compare("name")==0){ - card->setName(value); - }else if(key.compare("rarity")==0){ - card->setRarity (value.c_str()[0]); - }else if(key.compare("mana")==0){ - std::transform( value.begin(), value.end(), value.begin(),::tolower ); - card->setManaCost(value); - }else if(key.compare("type")==0){ - switch(value.c_str()[0]){ - case 'C': - card->setType( "Creature"); - break; - case 'A': - card->setType( "Artifact"); - card->setColor(MTG_COLOR_ARTIFACT); - if (value.c_str()[8] == ' ' && value.c_str()[9] == 'C') - card->setSubtype("Creature"); - break; - case 'E': - card->setType( "Enchantment"); - break; - case 'S': - card->setType( "Sorcery"); - break; - case 'B'://Basic Land - card->setColor(MTG_COLOR_LAND); - card->setType("Land"); - break; - case 'L': - card->setColor(MTG_COLOR_LAND); - card->setType( "Land"); - break; - case 'I': - card->setType( "Instant"); - break; - default: - card->setType( "Error"); - break; - - } - }else if(key.compare("power")==0){ - card->setPower (atoi(value.c_str())); - }else if(key.compare("subtype")==0){ - card->setSubtype(value); - }else if(key.compare("toughness")==0){ - card->setToughness(atoi(value.c_str())); - }else{ -} - - - return i; - -} - -void MTGAllCards::initCounters(){ - for (int i=0; i< MTG_NB_COLORS; i++){ - colorsCount[i] = NULL; - } -} - -void MTGAllCards::init(){ - mCache = NULL; - total_cards = 0; - initCounters(); - srand(time(0)); // initialize random -} - - - -int MTGAllCards::load(const char * config_file, const char * set_name,int autoload){ - conf_read_mode = 0; - int file_size = filesize(config_file); - conf_buffer = (char *) malloc(file_size); - read_cursor = 0; - // conf_fd = sceIoOpen(config_file, PSP_O_RDONLY, 0777); - read_file(config_file, conf_buffer, file_size ); - int set_id = MtgSets::SetsList->Add(set_name); - if (autoload){ - while(readConfLine(set_id)){}; - } - return total_cards; -} - -MTGAllCards::MTGAllCards(){ - init(); -} - -MTGAllCards::~MTGAllCards(){ -} - -void MTGAllCards::destroyAllCards(){ - for (int i= 0; i < total_cards; i++){ - delete collection[i]; - }; - -} - -MTGAllCards::MTGAllCards(const char * config_file, const char * set_name){ - MTGAllCards(config_file, set_name, NULL); -} - -MTGAllCards::MTGAllCards(TexturesCache * cache){ - init(); - mCache = cache; -} - -MTGAllCards::MTGAllCards(const char * config_file, const char * set_name, TexturesCache * cache){ - init(); - mCache = cache; - load(config_file,set_name, 0); -} - - -MTGCard * MTGAllCards::_(int i){ - if (i < total_cards) return collection[i]; - return NULL; -} - - -int MTGAllCards::randomCardId(){ - int id = (rand() % total_cards); - return collection[id]->getMTGId(); -} - - - -int MTGAllCards::countBySet(int setId){ - int result = 0; - for (int i=0; i< total_cards; i++){ - if(collection[i]->setId == setId){ - result++; - } - } - return result; -} - -//TODO more efficient way ? -int MTGAllCards::countByType(const char * _type){ - int result = 0; - for (int i=0; i< total_cards; i++){ - if(collection[i]->hasType(_type)){ - result++; - } - } - return result; -} - - -int MTGAllCards::countByColor(int color){ - if (colorsCount[color] == 0){ - for (int i=0; i< MTG_NB_COLORS; i++){ - colorsCount[i] = 0; - } - for (int i=0; i< total_cards; i++){ - int j = collection[i]->getColor(); - - colorsCount[j]++; - } - } - return colorsCount[color]; -} - -int MTGAllCards::totalCards(){ - return (total_cards); -} - -int MTGAllCards::readConfLine(int set_id){ - char buffer[BUFSIZE]; - read_cursor = readline(conf_buffer, buffer, read_cursor); - if (read_cursor){ - switch(conf_read_mode) { - case 0: - conf_read_mode = 1; - collection[total_cards] = NEW MTGCard(mCache,set_id); - break; - case 1: - if (buffer[0] == '[' && buffer[1] == '/'){ - conf_read_mode = 0; - total_cards++; - }else{ - processConfLine(buffer, collection[total_cards]); - } - break; - default: - break; - } - - }else{ - free (conf_buffer); - } - - return read_cursor; - - -} - - -MTGCard * MTGAllCards::getCardById(int id){ - int i; - for (i=0; igetMTGId(); - if (cardId == id){ - return collection[i]; - } - } - return 0; -} - - - -MTGDeck::MTGDeck(const char * config_file, TexturesCache * cache, MTGAllCards * _allcards){ - mCache = cache; - total_cards = 0; - allcards = _allcards; - filename = config_file; - std::ifstream file(config_file); - std::string s; - - if(file){ - while(std::getline(file,s)){ - int cardnb = atoi(s.c_str()); - if (cardnb) add(cardnb); - } - file.close(); - }else{ - //TODO Error management - } - - -} - - - -int MTGDeck::addRandomCards(int howmany, int setId, int rarity, const char * _subtype){ - int collectionTotal = allcards->totalCards(); - if (!collectionTotal) return 0; - if (setId == -1 && rarity == -1 && !_subtype){ - for (int i = 0; i < howmany; i++){ - int id = (rand() % collectionTotal); - add(allcards->_(id)); - } - return 1; - } - char subtype[4096]; - if (_subtype) - sprintf(subtype, _subtype); - - - int subcollection[TOTAL_NUMBER_OF_CARDS]; - int subtotal = 0; - for (int i = 0; i < collectionTotal; i++){ - MTGCard * card = allcards->_(i); - if ((setId == -1 || card->setId == setId) && - (rarity == -1 || card->getRarity()==rarity) && - (!_subtype || card->hasSubtype(subtype)) - ){ - subcollection[subtotal] = i; - subtotal++; - } - } - if (subtotal == 0) return 0; - for (int i = 0; i < howmany; i++){ - int id = (rand() % subtotal); - add(allcards->_(subcollection[id])); - } - return 1; -} - -int MTGDeck::add(int cardid){ - MTGCard * card = allcards->getCardById(cardid); - add(card); - return total_cards; -} - -int MTGDeck::add(MTGCard * card){ - if (!card) return 0; - collection[total_cards] = card; - ++total_cards; - initCounters(); - return total_cards; -} - - -int MTGDeck::removeAll(){ - total_cards = 0; - initCounters(); - return 1; -} - -int MTGDeck::remove(int cardid){ - MTGCard * card = getCardById(cardid); - return remove(card); -} - -int MTGDeck::remove(MTGCard * card){ - for (int i = 0; igetMTGId()); - file< +#include +using std::string; + +#include + +#if defined (WIN32) || defined (LINUX) +#include +#endif + + + + + +MtgSets * MtgSets::SetsList = NEW MtgSets(); + + + +MtgSets::MtgSets(){ + nb_items = 0; +} + +int MtgSets::Add(const char * name){ + string value = name; + values[nb_items] = value; + nb_items++; + return nb_items - 1; +} + + +int MTGAllCards::processConfLine(char *buffer, MTGCard *card){ + string s = buffer; + unsigned int i = s.find_first_of("="); + if (i == string::npos) return 0; + string key = s.substr(0,i); + string value = s.substr(i+1); + + if(key.compare( "auto")==0){ + card->addMagicText(value); + } + else if(key.compare( "alias")==0){ + card->alias=atoi(value.c_str()); + } + else if(key.compare( "target")==0){ + std::transform( value.begin(), value.end(), value.begin(),::tolower ); + card->spellTargetType=value; + } + else if(key.compare( "text")==0){ + card->setText(value); + }else if (key.compare("abilities")==0){ + //Specific Abilities + std::transform( value.begin(), value.end(), value.begin(),::tolower ); + for (int j = 0; j < NB_BASIC_ABILITIES; j++){ + unsigned int found = value.find(MTGBasicAbilities[j]); + if (found != string::npos){ + card->basicAbilities[j] = 1; + } + } + }else if(key.compare("id")==0){ + card->setMTGId(atoi(value.c_str())); + }else if(key.compare("name")==0){ + card->setName(value); + }else if(key.compare("rarity")==0){ + card->setRarity (value.c_str()[0]); + }else if(key.compare("mana")==0){ + std::transform( value.begin(), value.end(), value.begin(),::tolower ); + card->setManaCost(value); + }else if(key.compare("type")==0){ + switch(value.c_str()[0]){ + case 'C': + card->setType( "Creature"); + break; + case 'A': + card->setType( "Artifact"); + card->setColor(MTG_COLOR_ARTIFACT); + if (value.c_str()[8] == ' ' && value.c_str()[9] == 'C') + card->setSubtype("Creature"); + break; + case 'E': + card->setType( "Enchantment"); + break; + case 'S': + card->setType( "Sorcery"); + break; + case 'B'://Basic Land + card->setColor(MTG_COLOR_LAND); + card->setType("Land"); + break; + case 'L': + card->setColor(MTG_COLOR_LAND); + card->setType( "Land"); + break; + case 'I': + card->setType( "Instant"); + break; + default: + card->setType( "Error"); + break; + + } + }else if(key.compare("power")==0){ + card->setPower (atoi(value.c_str())); + }else if(key.compare("subtype")==0){ + card->setSubtype(value); + }else if(key.compare("toughness")==0){ + card->setToughness(atoi(value.c_str())); + }else{ + } + + + return i; + +} + +void MTGAllCards::initCounters(){ + for (int i=0; i< MTG_NB_COLORS; i++){ + colorsCount[i] = NULL; + } +} + +void MTGAllCards::init(){ + mCache = NULL; + total_cards = 0; + initCounters(); + srand(time(0)); // initialize random +} + + + +int MTGAllCards::load(const char * config_file, const char * set_name,int autoload){ + conf_read_mode = 0; + int file_size = filesize(config_file); + conf_buffer = (char *) malloc(file_size); + read_cursor = 0; + // conf_fd = sceIoOpen(config_file, PSP_O_RDONLY, 0777); + read_file(config_file, conf_buffer, file_size ); + int set_id = MtgSets::SetsList->Add(set_name); + if (autoload){ + while(readConfLine(set_id)){}; + } + return total_cards; +} + +MTGAllCards::MTGAllCards(){ + init(); +} + +MTGAllCards::~MTGAllCards(){ +} + +void MTGAllCards::destroyAllCards(){ + for (int i= 0; i < total_cards; i++){ + delete collection[i]; + }; + +} + +MTGAllCards::MTGAllCards(const char * config_file, const char * set_name){ + MTGAllCards(config_file, set_name, NULL); +} + +MTGAllCards::MTGAllCards(TexturesCache * cache){ + init(); + mCache = cache; +} + +MTGAllCards::MTGAllCards(const char * config_file, const char * set_name, TexturesCache * cache){ + init(); + mCache = cache; + load(config_file,set_name, 0); +} + + +MTGCard * MTGAllCards::_(int i){ + if (i < total_cards) return collection[i]; + return NULL; +} + + +int MTGAllCards::randomCardId(){ + int id = (rand() % total_cards); + return collection[id]->getMTGId(); +} + + + +int MTGAllCards::countBySet(int setId){ + int result = 0; + for (int i=0; i< total_cards; i++){ + if(collection[i]->setId == setId){ + result++; + } + } + return result; +} + +//TODO more efficient way ? +int MTGAllCards::countByType(const char * _type){ + int result = 0; + for (int i=0; i< total_cards; i++){ + if(collection[i]->hasType(_type)){ + result++; + } + } + return result; +} + + +int MTGAllCards::countByColor(int color){ + if (colorsCount[color] == 0){ + for (int i=0; i< MTG_NB_COLORS; i++){ + colorsCount[i] = 0; + } + for (int i=0; i< total_cards; i++){ + int j = collection[i]->getColor(); + + colorsCount[j]++; + } + } + return colorsCount[color]; +} + +int MTGAllCards::totalCards(){ + return (total_cards); +} + +int MTGAllCards::readConfLine(int set_id){ + char buffer[BUFSIZE]; + read_cursor = readline(conf_buffer, buffer, read_cursor); + if (read_cursor){ + switch(conf_read_mode) { + case 0: + conf_read_mode = 1; + collection[total_cards] = NEW MTGCard(mCache,set_id); + break; + case 1: + if (buffer[0] == '[' && buffer[1] == '/'){ + conf_read_mode = 0; + total_cards++; + }else{ + processConfLine(buffer, collection[total_cards]); + } + break; + default: + break; + } + + }else{ + free (conf_buffer); + } + + return read_cursor; + + +} + + +MTGCard * MTGAllCards::getCardById(int id){ + int i; + for (i=0; igetMTGId(); + if (cardId == id){ + return collection[i]; + } + } + return 0; +} + + + +MTGDeck::MTGDeck(const char * config_file, TexturesCache * cache, MTGAllCards * _allcards){ + mCache = cache; + total_cards = 0; + allcards = _allcards; + filename = config_file; + std::ifstream file(config_file); + std::string s; + + if(file){ + while(std::getline(file,s)){ + int cardnb = atoi(s.c_str()); + if (cardnb) add(cardnb); + } + file.close(); + }else{ + //TODO Error management + } + + +} + + + +int MTGDeck::addRandomCards(int howmany, int setId, int rarity, const char * _subtype){ + int collectionTotal = allcards->totalCards(); + if (!collectionTotal) return 0; + if (setId == -1 && rarity == -1 && !_subtype){ + for (int i = 0; i < howmany; i++){ + int id = (rand() % collectionTotal); + add(allcards->_(id)); + } + return 1; + } + char subtype[4096]; + if (_subtype) + sprintf(subtype, _subtype); + + + int subcollection[TOTAL_NUMBER_OF_CARDS]; + int subtotal = 0; + for (int i = 0; i < collectionTotal; i++){ + MTGCard * card = allcards->_(i); + if ((setId == -1 || card->setId == setId) && + (rarity == -1 || card->getRarity()==rarity) && + (!_subtype || card->hasSubtype(subtype)) + ){ + subcollection[subtotal] = i; + subtotal++; + } + } + if (subtotal == 0) return 0; + for (int i = 0; i < howmany; i++){ + int id = (rand() % subtotal); + add(allcards->_(subcollection[id])); + } + return 1; +} + +int MTGDeck::add(int cardid){ + MTGCard * card = allcards->getCardById(cardid); + add(card); + return total_cards; +} + +int MTGDeck::add(MTGCard * card){ + if (!card) return 0; + collection[total_cards] = card; + ++total_cards; + initCounters(); + return total_cards; +} + + +int MTGDeck::removeAll(){ + total_cards = 0; + initCounters(); + return 1; +} + +int MTGDeck::remove(int cardid){ + MTGCard * card = getCardById(cardid); + return remove(card); +} + +int MTGDeck::remove(MTGCard * card){ + for (int i = 0; igetMTGId()); + file<GetJLBFont("graphics/f3"); + mFont= GameApp::CommonRes->GetJLBFont("graphics/f3"); mFont->SetBase(0); // using 2nd font } @@ -17,39 +17,39 @@ void MTGGamePhase::Render(){ void MTGGamePhase::Update(float dt){ - int newState = GameObserver::GetInstance()->getCurrentGamePhase(); - if (newState != currentState){ - activeState = ACTIVE; - animation = 1; - currentState = newState; + int newState = GameObserver::GetInstance()->getCurrentGamePhase(); + if (newState != currentState){ + activeState = ACTIVE; + animation = 1; + currentState = newState; - switch (currentState){ + switch (currentState){ - default: break; - } + default: break; + } - } + } - - if (animation > 0){ + + if (animation > 0){ fprintf(stderr, "animation = %f", animation); animation -= dt *5 ; }else{ - activeState = INACTIVE; + activeState = INACTIVE; animation = 0; - } + } } void MTGGamePhase::CheckUserInput(float dt){ - GameObserver * game = GameObserver::GetInstance(); - if (activeState == INACTIVE){ - if (mEngine->GetButtonClick(PSP_CTRL_RTRIGGER) && game->currentActionPlayer == game->currentlyActing()) - { - activeState = ACTIVE; - game->userRequestNextGamePhase(); - } - } + GameObserver * game = GameObserver::GetInstance(); + if (activeState == INACTIVE){ + if (mEngine->GetButtonClick(PSP_CTRL_RTRIGGER) && game->currentActionPlayer == game->currentlyActing()) + { + activeState = ACTIVE; + game->userRequestNextGamePhase(); + } + } } diff --git a/projects/mtg/src/MTGGameZones.cpp b/projects/mtg/src/MTGGameZones.cpp index f682320ee..50f615c9f 100644 --- a/projects/mtg/src/MTGGameZones.cpp +++ b/projects/mtg/src/MTGGameZones.cpp @@ -1,314 +1,314 @@ -#include "../include/debug.h" -#include "../include/MTGGameZones.h" -#include "../include/Player.h" - -#if defined (WIN32) || defined (LINUX) -#include -#endif - -//------------------------------ -//Players Game -//------------------------------ - -MTGPlayerCards::MTGPlayerCards(MTGAllCards * _collection, int * idList, int idListSize){ - - init(); - int i; - collection = _collection; - for (i=0;igetCardById(idList[i]); - if (card){ - MTGCardInstance * newCard = NEW MTGCardInstance(card, this); - library->addCard(newCard); - } - } - - -} - -MTGPlayerCards::~MTGPlayerCards(){ - if(library) delete library; - if(graveyard) delete graveyard; - if(hand) delete hand; - if(inPlay) delete inPlay; - if(stack) delete stack; -} - -void MTGPlayerCards::setOwner(Player * player){ - library->setOwner(player); -} - -void MTGPlayerCards::initGame(int shuffle, int draw){ - if (shuffle) library->shuffle(); - if (draw){ - for (int i=0;i<7;i++){ - drawFromLibrary(); - } - } -} - -void MTGPlayerCards::drawFromLibrary(){ - MTGCardInstance * drownCard = library->draw(); - hand->addCard(drownCard); -} - -void MTGPlayerCards::init(){ - library = NEW MTGLibrary(); - graveyard = NEW MTGGraveyard(); - hand = NEW MTGHand(); - inPlay = NEW MTGInPlay(); - stack = NEW MTGStack(); -} - - -void MTGPlayerCards::showHand(){ - hand->debugPrint(); -} - - -void MTGPlayerCards::putInPlay(MTGCardInstance * card){ - hand->removeCard(card); - stack->removeCard(card); //Which one is it ??? - - inPlay->addCard(card); - card->summoningSickness = 1; - card->changedZoneRecently = 1.f; -} - -void MTGPlayerCards::putInGraveyard(MTGCardInstance * card){ - if (inPlay->hasCard(card)){ - putInZone(card,inPlay, graveyard); - }else if (stack->hasCard(card)){ - putInZone(card,stack, graveyard); - }else{ - putInZone(card,hand, graveyard); - } - -} - -void MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone * from, MTGGameZone * to){ - if (from->removeCard(card)){ - to->addCard(card); - card->changedZoneRecently = 1.f; - //if (to == graveyard){ - card->reset(); - //} - } -} - -void MTGPlayerCards::discardRandom(MTGGameZone * from){ - if (!from->nb_cards) - return; - int r = rand() % (from->nb_cards); - putInZone(from->cards[r],from, graveyard); -} - -int MTGPlayerCards::isInPlay(MTGCardInstance * card){ - if (inPlay->hasCard(card)){ - return 1; - } - return 0; -} - -//-------------------------------------- -// Zones specific code -//-------------------------------------- - -MTGGameZone::MTGGameZone(){ - nb_cards= 0; - lastCardDrawn = NULL; -} - -MTGGameZone::~MTGGameZone(){ - for (int i=0; iowner = player; - } - owner = player; -} - -MTGCardInstance * MTGGameZone::removeCard(MTGCardInstance * card){ - int i; - cardsMap.erase(card); - for (i=0; i<(nb_cards); i++) { - if (cards[i] == card){ - cards[i] = cards[nb_cards -1]; - nb_cards--; - return card; - } - } - return NULL; - -} - -MTGCardInstance * MTGGameZone::hasCard(MTGCardInstance * card){ - if (cardsMap.find(card) != cardsMap.end()) return card; - return NULL; - -} - -int MTGGameZone::countByType(const char * value){ - int result = 0 ; - for (int i=0; i<(nb_cards); i++) { - if (cards[i]->hasType(value)){ - result++; - } - } - return result; - -} - -int MTGGameZone::hasType(const char * value){ - for (int i=0; i<(nb_cards); i++) { - if (cards[i]->hasType(value)){ - return 1; - } - } - return 0; -} - - -void MTGGameZone::cleanupPhase(){ - for (int i=0; i<(nb_cards); i++) - (cards[i])->cleanup(); -} - -void MTGGameZone::shuffle(){ - int i; - for (i=0; i<(nb_cards); i++) { - int r = i + (rand() % (nb_cards-i)); // Random remaining position. - MTGCardInstance * temp = cards[i]; cards[i] = cards[r]; cards[r] = temp; - } - srand(time(0)); // initialize seed "randomly" TODO :improve -} - - - -void MTGGameZone::addCard(MTGCardInstance * card){ - if (!card) return; - cards[nb_cards] = card; - nb_cards++; - cardsMap[card] = 1; - -} - -MTGCardInstance * MTGGameZone::draw(){ - if (!nb_cards) return NULL; - nb_cards--; - lastCardDrawn = cards[nb_cards]; - cardsMap.erase(cards[nb_cards]); - return cards[nb_cards]; -} - -MTGCardInstance * MTGLibrary::draw(){ - if (!nb_cards) { - GameObserver::GetInstance()->gameOver = this->owner; - } - return MTGGameZone::draw(); -} - -void MTGGameZone::debugPrint(){ - int i; - for (i=0;imodel; - fprintf(stderr, "%s", card->getName()); - } -} - - - - - -//------------------------------ -int MTGInPlay::nbDefensers( MTGCardInstance * attacker){ - int result = 0; - MTGCardInstance * defenser = getNextDefenser(NULL, attacker); - while (defenser){ - result++; - defenser = getNextDefenser(defenser, attacker); - } - return result; -} - -//Return the number of creatures this card is banded with -//Number of creatures in the band is n+1 !!! -int MTGInPlay::nbPartners(MTGCardInstance * attacker){ - int result = 0; - if (!attacker->banding) return 0; - for (int i = 0; i < nb_cards; i ++){ - if (cards[i]->banding == attacker->banding) result++; - } - return result; -} - -MTGCardInstance * MTGInPlay::getNextDefenser(MTGCardInstance * previous, MTGCardInstance * attacker){ - int foundprevious = 0; - if (previous == NULL){ - foundprevious = 1; - } - for (int i = 0; i < nb_cards; i ++){ - MTGCardInstance * current = cards[i]; - if (current == previous){ - foundprevious = 1; - }else if (foundprevious && current->isDefenser() == attacker){ - return current; - } - } - return NULL; -} - -MTGCardInstance * MTGInPlay::getNextAttacker(MTGCardInstance * previous){ - int foundprevious = 0; - if (previous == NULL){ - foundprevious = 1; - } - for (int i = 0; i < nb_cards; i ++){ - MTGCardInstance * current = cards[i]; - if (current == previous){ - foundprevious = 1; - }else if (foundprevious && current->isAttacker()){ - return current; - } - } - return NULL; -} - -void MTGInPlay::untapAll(){ - int i; - for (i = 0; i < nb_cards; i ++){ - cards[i]->setUntapping(); - if (cards[i]->getBlockers()->isEmpty()){ -#if defined (WIN32) || defined (LINUX) -char buf[4096]; -sprintf(buf, "Can untap %s\n", cards[i]->getName()); -OutputDebugString(buf); -#endif - cards[i]->untap(); - } - } -} - - -//-------------------------- -void MTGLibrary::shuffleTopToBottom(int nbcards){ - if (nbcards>nb_cards) nbcards = nb_cards; - MTGCardInstance * _cards[MTG_MAX_PLAYER_CARDS]; - for (int i= nb_cards-nbcards; i<(nb_cards); i++) { - int r = i + (rand() % (nbcards-i)); // Random remaining position. - MTGCardInstance * temp = cards[i]; cards[i] = cards[r]; cards[r] = temp; - } - for (int i= 0; i < nbcards; i++){ - _cards[i] = cards[nb_cards - 1 - i]; - } - for (int i = nbcards; i < nb_cards; i++){ - _cards[i] = cards[i - nb_cards]; - } - for (int i=0 ; i < nb_cards; i++){ - cards[i] = _cards[i]; - } -} +#include "../include/debug.h" +#include "../include/MTGGameZones.h" +#include "../include/Player.h" + +#if defined (WIN32) || defined (LINUX) +#include +#endif + +//------------------------------ +//Players Game +//------------------------------ + +MTGPlayerCards::MTGPlayerCards(MTGAllCards * _collection, int * idList, int idListSize){ + + init(); + int i; + collection = _collection; + for (i=0;igetCardById(idList[i]); + if (card){ + MTGCardInstance * newCard = NEW MTGCardInstance(card, this); + library->addCard(newCard); + } + } + + +} + +MTGPlayerCards::~MTGPlayerCards(){ + if(library) delete library; + if(graveyard) delete graveyard; + if(hand) delete hand; + if(inPlay) delete inPlay; + if(stack) delete stack; +} + +void MTGPlayerCards::setOwner(Player * player){ + library->setOwner(player); +} + +void MTGPlayerCards::initGame(int shuffle, int draw){ + if (shuffle) library->shuffle(); + if (draw){ + for (int i=0;i<7;i++){ + drawFromLibrary(); + } + } +} + +void MTGPlayerCards::drawFromLibrary(){ + MTGCardInstance * drownCard = library->draw(); + hand->addCard(drownCard); +} + +void MTGPlayerCards::init(){ + library = NEW MTGLibrary(); + graveyard = NEW MTGGraveyard(); + hand = NEW MTGHand(); + inPlay = NEW MTGInPlay(); + stack = NEW MTGStack(); +} + + +void MTGPlayerCards::showHand(){ + hand->debugPrint(); +} + + +void MTGPlayerCards::putInPlay(MTGCardInstance * card){ + hand->removeCard(card); + stack->removeCard(card); //Which one is it ??? + + inPlay->addCard(card); + card->summoningSickness = 1; + card->changedZoneRecently = 1.f; +} + +void MTGPlayerCards::putInGraveyard(MTGCardInstance * card){ + if (inPlay->hasCard(card)){ + putInZone(card,inPlay, graveyard); + }else if (stack->hasCard(card)){ + putInZone(card,stack, graveyard); + }else{ + putInZone(card,hand, graveyard); + } + +} + +void MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone * from, MTGGameZone * to){ + if (from->removeCard(card)){ + to->addCard(card); + card->changedZoneRecently = 1.f; + //if (to == graveyard){ + card->reset(); + //} + } +} + +void MTGPlayerCards::discardRandom(MTGGameZone * from){ + if (!from->nb_cards) + return; + int r = rand() % (from->nb_cards); + putInZone(from->cards[r],from, graveyard); +} + +int MTGPlayerCards::isInPlay(MTGCardInstance * card){ + if (inPlay->hasCard(card)){ + return 1; + } + return 0; +} + +//-------------------------------------- +// Zones specific code +//-------------------------------------- + +MTGGameZone::MTGGameZone(){ + nb_cards= 0; + lastCardDrawn = NULL; +} + +MTGGameZone::~MTGGameZone(){ + for (int i=0; iowner = player; + } + owner = player; +} + +MTGCardInstance * MTGGameZone::removeCard(MTGCardInstance * card){ + int i; + cardsMap.erase(card); + for (i=0; i<(nb_cards); i++) { + if (cards[i] == card){ + cards[i] = cards[nb_cards -1]; + nb_cards--; + return card; + } + } + return NULL; + +} + +MTGCardInstance * MTGGameZone::hasCard(MTGCardInstance * card){ + if (cardsMap.find(card) != cardsMap.end()) return card; + return NULL; + +} + +int MTGGameZone::countByType(const char * value){ + int result = 0 ; + for (int i=0; i<(nb_cards); i++) { + if (cards[i]->hasType(value)){ + result++; + } + } + return result; + +} + +int MTGGameZone::hasType(const char * value){ + for (int i=0; i<(nb_cards); i++) { + if (cards[i]->hasType(value)){ + return 1; + } + } + return 0; +} + + +void MTGGameZone::cleanupPhase(){ + for (int i=0; i<(nb_cards); i++) + (cards[i])->cleanup(); +} + +void MTGGameZone::shuffle(){ + int i; + for (i=0; i<(nb_cards); i++) { + int r = i + (rand() % (nb_cards-i)); // Random remaining position. + MTGCardInstance * temp = cards[i]; cards[i] = cards[r]; cards[r] = temp; + } + srand(time(0)); // initialize seed "randomly" TODO :improve +} + + + +void MTGGameZone::addCard(MTGCardInstance * card){ + if (!card) return; + cards[nb_cards] = card; + nb_cards++; + cardsMap[card] = 1; + +} + +MTGCardInstance * MTGGameZone::draw(){ + if (!nb_cards) return NULL; + nb_cards--; + lastCardDrawn = cards[nb_cards]; + cardsMap.erase(cards[nb_cards]); + return cards[nb_cards]; +} + +MTGCardInstance * MTGLibrary::draw(){ + if (!nb_cards) { + GameObserver::GetInstance()->gameOver = this->owner; + } + return MTGGameZone::draw(); +} + +void MTGGameZone::debugPrint(){ + int i; + for (i=0;imodel; + fprintf(stderr, "%s", card->getName()); + } +} + + + + + +//------------------------------ +int MTGInPlay::nbDefensers( MTGCardInstance * attacker){ + int result = 0; + MTGCardInstance * defenser = getNextDefenser(NULL, attacker); + while (defenser){ + result++; + defenser = getNextDefenser(defenser, attacker); + } + return result; +} + +//Return the number of creatures this card is banded with +//Number of creatures in the band is n+1 !!! +int MTGInPlay::nbPartners(MTGCardInstance * attacker){ + int result = 0; + if (!attacker->banding) return 0; + for (int i = 0; i < nb_cards; i ++){ + if (cards[i]->banding == attacker->banding) result++; + } + return result; +} + +MTGCardInstance * MTGInPlay::getNextDefenser(MTGCardInstance * previous, MTGCardInstance * attacker){ + int foundprevious = 0; + if (previous == NULL){ + foundprevious = 1; + } + for (int i = 0; i < nb_cards; i ++){ + MTGCardInstance * current = cards[i]; + if (current == previous){ + foundprevious = 1; + }else if (foundprevious && current->isDefenser() == attacker){ + return current; + } + } + return NULL; +} + +MTGCardInstance * MTGInPlay::getNextAttacker(MTGCardInstance * previous){ + int foundprevious = 0; + if (previous == NULL){ + foundprevious = 1; + } + for (int i = 0; i < nb_cards; i ++){ + MTGCardInstance * current = cards[i]; + if (current == previous){ + foundprevious = 1; + }else if (foundprevious && current->isAttacker()){ + return current; + } + } + return NULL; +} + +void MTGInPlay::untapAll(){ + int i; + for (i = 0; i < nb_cards; i ++){ + cards[i]->setUntapping(); + if (cards[i]->getBlockers()->isEmpty()){ +#if defined (WIN32) || defined (LINUX) + char buf[4096]; + sprintf(buf, "Can untap %s\n", cards[i]->getName()); + OutputDebugString(buf); +#endif + cards[i]->untap(); + } + } +} + + +//-------------------------- +void MTGLibrary::shuffleTopToBottom(int nbcards){ + if (nbcards>nb_cards) nbcards = nb_cards; + MTGCardInstance * _cards[MTG_MAX_PLAYER_CARDS]; + for (int i= nb_cards-nbcards; i<(nb_cards); i++) { + int r = i + (rand() % (nbcards-i)); // Random remaining position. + MTGCardInstance * temp = cards[i]; cards[i] = cards[r]; cards[r] = temp; + } + for (int i= 0; i < nbcards; i++){ + _cards[i] = cards[nb_cards - 1 - i]; + } + for (int i = nbcards; i < nb_cards; i++){ + _cards[i] = cards[i - nb_cards]; + } + for (int i=0 ; i < nb_cards; i++){ + cards[i] = _cards[i]; + } +} diff --git a/projects/mtg/src/MTGGuiHand.cpp b/projects/mtg/src/MTGGuiHand.cpp index 53b982445..766ea2050 100644 --- a/projects/mtg/src/MTGGuiHand.cpp +++ b/projects/mtg/src/MTGGuiHand.cpp @@ -7,26 +7,26 @@ MTGGuiHand::MTGGuiHand(int id, GameObserver * _game):GuiCardsController(id, _gam mAnimState = 0; currentPlayer = NULL; mFont = GameApp::CommonRes->GetJLBFont("graphics/f3"); - for (int i = 0; i < 2; i++){ - currentId[i] = 0; - } + for (int i = 0; i < 2; i++){ + currentId[i] = 0; + } } void MTGGuiHand::updateCards(){ - Player * player = GameObserver::GetInstance()->currentlyActing(); - if (player->isAI()) player = GameObserver::GetInstance()->players[0]; + Player * player = GameObserver::GetInstance()->currentlyActing(); + if (player->isAI()) player = GameObserver::GetInstance()->players[0]; int nb_cards = player->game->hand->nb_cards; if (mCount != nb_cards || player != currentPlayer ){ //if the number of cards has changed, then an update occured (is this test engouh ?) - resetObjects(); - if (currentId[player->getId()] >= nb_cards) currentId[player->getId()] = nb_cards - 1; - for (int i = 0;igame->hand->cards[i],(float)40, (float)450 - (nb_cards-i) *35, SCREEN_HEIGHT_F - mAnimState*60, i == currentId[player->getId()]); - Add(object); - if ( i == currentId[player->getId()]) mCurr = i; - } - currentPlayer = player; + resetObjects(); + if (currentId[player->getId()] >= nb_cards) currentId[player->getId()] = nb_cards - 1; + for (int i = 0;igame->hand->cards[i],(float)40, (float)450 - (nb_cards-i) *35, SCREEN_HEIGHT_F - mAnimState*60, i == currentId[player->getId()]); + Add(object); + if ( i == currentId[player->getId()]) mCurr = i; + } + currentPlayer = player; } @@ -35,14 +35,14 @@ void MTGGuiHand::updateCards(){ void MTGGuiHand::Update(float dt){ updateCards(); - for (int i=0;iy= SCREEN_HEIGHT - mAnimState*60; } - } + } GuiCardsController::Update(dt); - currentId[game->currentlyActing()->getId()] = mCurr; + currentId[game->currentlyActing()->getId()] = mCurr; } @@ -72,7 +72,7 @@ void MTGGuiHand::CheckUserInput(float dt){ mShowHand = HAND_HIDE; } } - + if (mShowHand == HAND_HIDE || currentPlayer->isAI()){ modal = 0; }else{ @@ -85,17 +85,17 @@ void MTGGuiHand::CheckUserInput(float dt){ void MTGGuiHand::Render(){ - if (mShowHand != HAND_HIDE){ - // if (currentPlayer && !currentPlayer->isAI()){ - RenderMessageBackground(440-mCount * 35 , SCREEN_HEIGHT - mAnimState*60 - 10, mCount * 35 + 20, 70); - for (int i=0;iRender(); - } - } - if (mCount && mObjects[mCurr] != NULL){ - mObjects[mCurr]->Render(); - if (showBigCards) ((CardGui *)mObjects[mCurr])->RenderBig(10); - } - } + if (mShowHand != HAND_HIDE){ + // if (currentPlayer && !currentPlayer->isAI()){ + RenderMessageBackground(440-mCount * 35 , SCREEN_HEIGHT - mAnimState*60 - 10, mCount * 35 + 20, 70); + for (int i=0;iRender(); + } + } + if (mCount && mObjects[mCurr] != NULL){ + mObjects[mCurr]->Render(); + if (showBigCards) ((CardGui *)mObjects[mCurr])->RenderBig(10); + } + } } diff --git a/projects/mtg/src/MTGGuiPlay.cpp b/projects/mtg/src/MTGGuiPlay.cpp index 9ad8a1df9..71973226c 100644 --- a/projects/mtg/src/MTGGuiPlay.cpp +++ b/projects/mtg/src/MTGGuiPlay.cpp @@ -1,405 +1,405 @@ -/* This class handles the display on the main game screen : -cards in play, graveyard, library, games phases, Players avatars -*/ - -#include "../include/debug.h" -#include "../include/MTGGuiPlay.h" -#include "../include/MTGCardInstance.h" -#include "../include/CardGui.h" -#include "../include/CardDisplay.h" - -#define ZX_MAIN 100 -#define ZY_MAIN 22 -#define ZH_CREATURES 50 -#define Z_CARDWIDTH 30 -#define Z_CARDHEIGHT 40 -#define Z_MAIN_NBCARDS 7 -#define Z_SPELLS_NBCARDS 3 -#define ZX_SPELL 450 -#define ZY_SPELL 22 - - - - -MTGGuiPlay::MTGGuiPlay(int id, GameObserver * _game):PlayGuiObjectController(id, _game){ - currentPlayer = NULL; - offset = 0; - - - mPhaseBarTexture = JRenderer::GetInstance()->LoadTexture("graphics/phasebar.png", TEX_TYPE_USE_VRAM); - for (int i=0; i < 12; i++){ - phaseIcons[2*i] = NEW JQuad(mPhaseBarTexture, i*28, 0, 28, 28); - phaseIcons[2*i + 1] = NEW JQuad(mPhaseBarTexture, i*28, 28, 28, 28); - } - mGlitter = NEW JQuad(mPhaseBarTexture, 392, 0, 5, 5); - mGlitter->SetHotSpot(2.5,2.5); - mGlitterAlpha = -1; - mFont= GameApp::CommonRes->GetJLBFont("graphics/f3"); - mFont->SetScale(0.75); - - - mIconsTexture = JRenderer::GetInstance()->LoadTexture("graphics/menuicons.png", TEX_TYPE_USE_VRAM); - //load all the icon images - mIcons[MTG_COLOR_ARTIFACT] = NEW JQuad(mIconsTexture, 10 + 6*32, 32, 32, 32); - mIcons[MTG_COLOR_LAND] = NEW JQuad(mIconsTexture, 10 + 5*32, 32, 32, 32); - mIcons[MTG_COLOR_WHITE] = NEW JQuad(mIconsTexture, 10 + 4*32, 32, 32, 32); - mIcons[MTG_COLOR_RED] = NEW JQuad(mIconsTexture, 10 + 3*32, 32, 32, 32); - mIcons[MTG_COLOR_BLACK] = NEW JQuad(mIconsTexture, 10 + 2*32, 32, 32, 32); - mIcons[MTG_COLOR_BLUE] = NEW JQuad(mIconsTexture, 10 + 1*32, 32, 32, 32); - mIcons[MTG_COLOR_GREEN] = NEW JQuad(mIconsTexture, 10 + 0*32, 32, 32, 32); - for (int i=0; i < 7; i++){ - mIcons[i]->SetHotSpot(16,16); - } - - mBgTex = JRenderer::GetInstance()->LoadTexture("graphics/background.png", TEX_TYPE_USE_VRAM); - mBg = NEW JQuad(mBgTex, 0, 0, 480, 272); - - mBgTex2 = JRenderer::GetInstance()->LoadTexture("graphics/back.jpg", TEX_TYPE_USE_VRAM); - mBg2 = NEW JQuad(mBgTex2, 0, 0, 480, 255); - for (int i= 0; i < 4; i++){ - alphaBg[i] = 255; - } - alphaBg[0] = 0; - AddPlayersGuiInfo(); -} - - -CardGui * MTGGuiPlay::getByCard(MTGCardInstance * card){ - for (int i = offset; i < mCount; i++){ - CardGui * cardg = (CardGui *)mObjects[i]; - if(cardg && cardg->card == card){ - return cardg; - } - } - return NULL; - -} - -void MTGGuiPlay::initCardsDisplay(){ - for (int i = 0; i < SCREEN_WIDTH/5; i++){ - for(int j=0; j < SCREEN_HEIGHT/5; j++){ - cardsGrid[i][j] = NULL; - } - } - cards_x_limit = 12; - nb_creatures = 0; - nb_lands = 0; - nb_spells = 0; -} - - -void MTGGuiPlay::adjustCardPosition(CardGui * cardg){ - int x5 = cardg->x / 5; - int y5 = cardg->y / 5; - - while (cardsGrid[x5][y5] && x5 x = x5 * 5; - cardg->y = y5 * 5; - cardsGrid[x5][y5] = cardg->card; -} - -void MTGGuiPlay::setCardPosition(CardGui * cardg, int player, int playerTurn, int spellMode){ - MTGCardInstance * card = cardg->card; - if (card->target) - return; - if (spellMode && (card->isACreature() || card->hasType("land"))) return; - if (!spellMode && !card->isACreature() && !card->hasType("land")) return; - if (card->isACreature()){ - int x_offset = nb_creatures % cards_x_limit; - int y_offset = nb_creatures / cards_x_limit; - cardg->x= ZX_MAIN + (Z_CARDWIDTH * x_offset); - cardg->y=ZY_MAIN + ZH_CREATURES + (Z_CARDHEIGHT * y_offset) + 100 * (1-player); - nb_creatures++; - - if (playerTurn){ - if (card->isAttacker()){ - cardg->y=122 + 30 * (1-player); - } - }else{ - if (card->isDefenser()){ - CardGui * targetg = getByCard(card->isDefenser()); - if (targetg) cardg->x = targetg->x; - cardg->y=122 + 30 * (1-player); - } - } - - }else if(card->hasType("land")){ - int x_offset = nb_lands % cards_x_limit; - int y_offset = nb_lands/ cards_x_limit; - cardg->x=ZX_MAIN + (Z_CARDWIDTH * x_offset); - cardg->y=ZY_MAIN + (Z_CARDHEIGHT * y_offset) + 200 * (1-player); - nb_lands++; - }else{ - int y_offset = nb_spells % Z_SPELLS_NBCARDS; - int x_offset = nb_spells/ Z_SPELLS_NBCARDS; - cardg->x=ZX_SPELL - (Z_CARDWIDTH * x_offset); - cardg->y=ZY_SPELL + (Z_CARDHEIGHT * y_offset) + 125 * (1-player); - nb_spells++; - cards_x_limit = 12 - (nb_spells + 2)/ Z_SPELLS_NBCARDS; - } - adjustCardPosition(cardg); -} - - -void MTGGuiPlay::setTargettingCardPosition(CardGui * cardg, int player, int playerTurn){ - MTGCardInstance * card = cardg->card; - MTGCardInstance * target = card->target; - if (!target) - return; - CardGui * targetg = getByCard(target); - if (targetg){ - cardg->y=targetg->y + 5; - cardg->x=targetg->x + 5; - } - adjustCardPosition(cardg); - return; -} - -void MTGGuiPlay::updateCards(){ - GameObserver * game = GameObserver::GetInstance(); - Player * player = game->players[0]; - int player0Mode =(game->currentPlayer == player); - int nb_cards = player->game->inPlay->nb_cards; - MTGCardInstance * attackers[MAX_ATTACKERS]; - for (int i = 0; i players[1]; - int opponent_cards = opponent ->game->inPlay->nb_cards; - if (mCount - offset != (nb_cards+opponent_cards) || game->currentPlayer != currentPlayer ){ //if the number of cards has changed, then an update occured (is this test engouh ?) - resetObjects(); - AddPlayersGuiInfo(); - offset = mCount; - - bool hasFocus = player0Mode; - - for (int i = 0;igame->inPlay->cards[i],40, i*35 + 10, 200, hasFocus); - Add(object); - hasFocus = false; - } - hasFocus = !player0Mode; - for (int i = 0;igame->inPlay->cards[i],40, i*35 + 10, 10, hasFocus); - Add(object); - hasFocus = false; - } - - currentPlayer = game->currentPlayer; - } - - - //This is just so that we display the cards of the current player first, so that blockers are correctly positionned - for (int j= 0; j < 2; j++){ - initCardsDisplay(); - if (j != player0Mode){ - for (int i =0; iplayers[0])); - Add(NEW GuiAvatar(-2,50,2,30,false,GameObserver::GetInstance()->players[1])); - - Add(NEW GuiGraveyard(-3,30,40,150,false, GameObserver::GetInstance()->players[0])); - Add(NEW GuiLibrary(-4,30,40,180,false, GameObserver::GetInstance()->players[0])); - - - Add(NEW GuiGraveyard(-5,30,40,30,false, GameObserver::GetInstance()->players[1])); - Add(NEW GuiLibrary(-6,30,40,60,false, GameObserver::GetInstance()->players[1])); - } -} - -void MTGGuiPlay::Update(float dt){ - updateCards(); - PlayGuiObjectController::Update(dt); - GameObserver * game = GameObserver::GetInstance(); -} - - - -void MTGGuiPlay::CheckUserInput(float dt){ - for (int i = 2; i<6;i++){ - GuiGameZone * zone = (GuiGameZone *)mObjects[i]; - if (zone->showCards){ - zone->cd->CheckUserInput(dt); - return; - } - } - PlayGuiObjectController::CheckUserInput(dt); - - -} - - -void MTGGuiPlay::RenderPlayerInfo(int playerid){ - GameObserver * game = GameObserver::GetInstance(); - JRenderer * r = JRenderer::GetInstance(); - Player * player = GameObserver::GetInstance()->players[playerid]; - int life = player->life; - - //Avatar - GuiAvatar * avatar = (GuiAvatar *)mObjects[3*playerid]; - avatar->Render(); - - - - //Mana - ManaCost * cost = player->getManaPool(); - int nbicons = 0; - for (int j=0; j<6;j++){ - int value = cost->getCost(j); - for (int i=0; iRenderQuad(mIcons[j],x,y,0,0.5, 0.5); - nbicons++; - } - } -} - - -void MTGGuiPlay::RenderPhaseBar(){ - GameObserver * game = GameObserver::GetInstance(); - JRenderer * renderer = JRenderer::GetInstance(); - int currentPhase = game->getCurrentGamePhase(); - for (int i=0; i < 12; i++){ - int index = 2*i + 1 ; - if (i==currentPhase-1){ - index-=1; - } - renderer->RenderQuad(phaseIcons[index], 200 + 14*i,0,0,0.5,0.5); - } - mFont->SetScale(0.70); - if (game->currentlyActing()->isAI()){ - mFont->SetColor(ARGB(255,128,128,128)); - }else{ - mFont->SetColor(ARGB(255,255,255,255)); - } - mFont->DrawString(MTGPhaseNames[currentPhase], 375, 0); -} - -void MTGGuiPlay::Render(){ - JRenderer * renderer = JRenderer::GetInstance(); - - //alphaBg[1] = 255; - //alphaBg[2]= 255; - //alphaBg[3] = 255; - //mBg2->SetColor(ARGB(alphaBg[0], alphaBg[1],alphaBg[2],alphaBg[3])); -renderer->RenderQuad(mBg2,0,17); - - if (game->currentGamePhase >=MTG_PHASE_COMBATBEGIN && game->currentGamePhase < MTG_PHASE_COMBATEND){ - if (alphaBg[0] < 50){ - alphaBg[3]-=12; - alphaBg[2]-=12; - alphaBg[0]+=3; - } - alphaBg[1] = 255; - - }else{ - if (alphaBg[0]){ - alphaBg[0]-=3; - alphaBg[3]+=12; - alphaBg[2]+=12; - } - alphaBg[1] = 255; - } - renderer->FillRect(0,0,480,272,ARGB(alphaBg[0], alphaBg[1],alphaBg[2],alphaBg[3])); - - renderer->RenderQuad(mBg,0,0); - - for (int i=0;iRender(); - } - } - - RenderPhaseBar(); - RenderPlayerInfo(0); - RenderPlayerInfo(1); - - if (mCount && mObjects[mCurr] != NULL){ - mObjects[mCurr]->Render(); - if (hasFocus && mCurr >= offset && showBigCards) - ((CardGui *)mObjects[mCurr])->RenderBig(); - } - - if (mGlitterAlpha < 0){ - mGlitterAlpha = 510; - int position = rand() % 2; - if (position){ - mGlitterX = 65 + rand() % (420); - mGlitterY = 17 + rand() % (5); - }else{ - mGlitterX = 65 + rand() % (5); - mGlitterY = 15 + rand() % (250); - } - } - mGlitter->SetColor(ARGB((255-abs(255-mGlitterAlpha)),240,240,255)); - renderer->RenderQuad(mGlitter,mGlitterX,mGlitterY, (float)(mGlitterAlpha)/(float)255, 1.2*float(mGlitterAlpha)/float(255),1.2*float(mGlitterAlpha)/float(255)); - mGlitterAlpha-=10; - -} - -MTGGuiPlay::~MTGGuiPlay(){ - LOG("==Destroying MTGGuiPlay=="); - delete mBg; - delete mBgTex; - for (int i=0; i < 7; i++){ - delete mIcons[i]; - } - delete mIconsTexture; - delete mGlitter; - for (int i=0; i < 12; i++){ - delete phaseIcons[2*i] ; - delete phaseIcons[2*i + 1]; - } - delete mPhaseBarTexture; - - SAFE_DELETE(mBg2); - SAFE_DELETE(mBgTex2); - - LOG("==Destroying MTGGuiPlay Successful=="); - -} +/* This class handles the display on the main game screen : + cards in play, graveyard, library, games phases, Players avatars +*/ + +#include "../include/debug.h" +#include "../include/MTGGuiPlay.h" +#include "../include/MTGCardInstance.h" +#include "../include/CardGui.h" +#include "../include/CardDisplay.h" + +#define ZX_MAIN 100 +#define ZY_MAIN 22 +#define ZH_CREATURES 50 +#define Z_CARDWIDTH 30 +#define Z_CARDHEIGHT 40 +#define Z_MAIN_NBCARDS 7 +#define Z_SPELLS_NBCARDS 3 +#define ZX_SPELL 450 +#define ZY_SPELL 22 + + + + +MTGGuiPlay::MTGGuiPlay(int id, GameObserver * _game):PlayGuiObjectController(id, _game){ + currentPlayer = NULL; + offset = 0; + + + mPhaseBarTexture = JRenderer::GetInstance()->LoadTexture("graphics/phasebar.png", TEX_TYPE_USE_VRAM); + for (int i=0; i < 12; i++){ + phaseIcons[2*i] = NEW JQuad(mPhaseBarTexture, i*28, 0, 28, 28); + phaseIcons[2*i + 1] = NEW JQuad(mPhaseBarTexture, i*28, 28, 28, 28); + } + mGlitter = NEW JQuad(mPhaseBarTexture, 392, 0, 5, 5); + mGlitter->SetHotSpot(2.5,2.5); + mGlitterAlpha = -1; + mFont= GameApp::CommonRes->GetJLBFont("graphics/f3"); + mFont->SetScale(0.75); + + + mIconsTexture = JRenderer::GetInstance()->LoadTexture("graphics/menuicons.png", TEX_TYPE_USE_VRAM); + //load all the icon images + mIcons[MTG_COLOR_ARTIFACT] = NEW JQuad(mIconsTexture, 10 + 6*32, 32, 32, 32); + mIcons[MTG_COLOR_LAND] = NEW JQuad(mIconsTexture, 10 + 5*32, 32, 32, 32); + mIcons[MTG_COLOR_WHITE] = NEW JQuad(mIconsTexture, 10 + 4*32, 32, 32, 32); + mIcons[MTG_COLOR_RED] = NEW JQuad(mIconsTexture, 10 + 3*32, 32, 32, 32); + mIcons[MTG_COLOR_BLACK] = NEW JQuad(mIconsTexture, 10 + 2*32, 32, 32, 32); + mIcons[MTG_COLOR_BLUE] = NEW JQuad(mIconsTexture, 10 + 1*32, 32, 32, 32); + mIcons[MTG_COLOR_GREEN] = NEW JQuad(mIconsTexture, 10 + 0*32, 32, 32, 32); + for (int i=0; i < 7; i++){ + mIcons[i]->SetHotSpot(16,16); + } + + mBgTex = JRenderer::GetInstance()->LoadTexture("graphics/background.png", TEX_TYPE_USE_VRAM); + mBg = NEW JQuad(mBgTex, 0, 0, 480, 272); + + mBgTex2 = JRenderer::GetInstance()->LoadTexture("graphics/back.jpg", TEX_TYPE_USE_VRAM); + mBg2 = NEW JQuad(mBgTex2, 0, 0, 480, 255); + for (int i= 0; i < 4; i++){ + alphaBg[i] = 255; + } + alphaBg[0] = 0; + AddPlayersGuiInfo(); +} + + +CardGui * MTGGuiPlay::getByCard(MTGCardInstance * card){ + for (int i = offset; i < mCount; i++){ + CardGui * cardg = (CardGui *)mObjects[i]; + if(cardg && cardg->card == card){ + return cardg; + } + } + return NULL; + +} + +void MTGGuiPlay::initCardsDisplay(){ + for (int i = 0; i < SCREEN_WIDTH/5; i++){ + for(int j=0; j < SCREEN_HEIGHT/5; j++){ + cardsGrid[i][j] = NULL; + } + } + cards_x_limit = 12; + nb_creatures = 0; + nb_lands = 0; + nb_spells = 0; +} + + +void MTGGuiPlay::adjustCardPosition(CardGui * cardg){ + int x5 = cardg->x / 5; + int y5 = cardg->y / 5; + + while (cardsGrid[x5][y5] && x5 x = x5 * 5; + cardg->y = y5 * 5; + cardsGrid[x5][y5] = cardg->card; +} + +void MTGGuiPlay::setCardPosition(CardGui * cardg, int player, int playerTurn, int spellMode){ + MTGCardInstance * card = cardg->card; + if (card->target) + return; + if (spellMode && (card->isACreature() || card->hasType("land"))) return; + if (!spellMode && !card->isACreature() && !card->hasType("land")) return; + if (card->isACreature()){ + int x_offset = nb_creatures % cards_x_limit; + int y_offset = nb_creatures / cards_x_limit; + cardg->x= ZX_MAIN + (Z_CARDWIDTH * x_offset); + cardg->y=ZY_MAIN + ZH_CREATURES + (Z_CARDHEIGHT * y_offset) + 100 * (1-player); + nb_creatures++; + + if (playerTurn){ + if (card->isAttacker()){ + cardg->y=122 + 30 * (1-player); + } + }else{ + if (card->isDefenser()){ + CardGui * targetg = getByCard(card->isDefenser()); + if (targetg) cardg->x = targetg->x; + cardg->y=122 + 30 * (1-player); + } + } + + }else if(card->hasType("land")){ + int x_offset = nb_lands % cards_x_limit; + int y_offset = nb_lands/ cards_x_limit; + cardg->x=ZX_MAIN + (Z_CARDWIDTH * x_offset); + cardg->y=ZY_MAIN + (Z_CARDHEIGHT * y_offset) + 200 * (1-player); + nb_lands++; + }else{ + int y_offset = nb_spells % Z_SPELLS_NBCARDS; + int x_offset = nb_spells/ Z_SPELLS_NBCARDS; + cardg->x=ZX_SPELL - (Z_CARDWIDTH * x_offset); + cardg->y=ZY_SPELL + (Z_CARDHEIGHT * y_offset) + 125 * (1-player); + nb_spells++; + cards_x_limit = 12 - (nb_spells + 2)/ Z_SPELLS_NBCARDS; + } + adjustCardPosition(cardg); +} + + +void MTGGuiPlay::setTargettingCardPosition(CardGui * cardg, int player, int playerTurn){ + MTGCardInstance * card = cardg->card; + MTGCardInstance * target = card->target; + if (!target) + return; + CardGui * targetg = getByCard(target); + if (targetg){ + cardg->y=targetg->y + 5; + cardg->x=targetg->x + 5; + } + adjustCardPosition(cardg); + return; +} + +void MTGGuiPlay::updateCards(){ + GameObserver * game = GameObserver::GetInstance(); + Player * player = game->players[0]; + int player0Mode =(game->currentPlayer == player); + int nb_cards = player->game->inPlay->nb_cards; + MTGCardInstance * attackers[MAX_ATTACKERS]; + for (int i = 0; i players[1]; + int opponent_cards = opponent ->game->inPlay->nb_cards; + if (mCount - offset != (nb_cards+opponent_cards) || game->currentPlayer != currentPlayer ){ //if the number of cards has changed, then an update occured (is this test engouh ?) + resetObjects(); + AddPlayersGuiInfo(); + offset = mCount; + + bool hasFocus = player0Mode; + + for (int i = 0;igame->inPlay->cards[i],40, i*35 + 10, 200, hasFocus); + Add(object); + hasFocus = false; + } + hasFocus = !player0Mode; + for (int i = 0;igame->inPlay->cards[i],40, i*35 + 10, 10, hasFocus); + Add(object); + hasFocus = false; + } + + currentPlayer = game->currentPlayer; + } + + + //This is just so that we display the cards of the current player first, so that blockers are correctly positionned + for (int j= 0; j < 2; j++){ + initCardsDisplay(); + if (j != player0Mode){ + for (int i =0; iplayers[0])); + Add(NEW GuiAvatar(-2,50,2,30,false,GameObserver::GetInstance()->players[1])); + + Add(NEW GuiGraveyard(-3,30,40,150,false, GameObserver::GetInstance()->players[0])); + Add(NEW GuiLibrary(-4,30,40,180,false, GameObserver::GetInstance()->players[0])); + + + Add(NEW GuiGraveyard(-5,30,40,30,false, GameObserver::GetInstance()->players[1])); + Add(NEW GuiLibrary(-6,30,40,60,false, GameObserver::GetInstance()->players[1])); + } +} + +void MTGGuiPlay::Update(float dt){ + updateCards(); + PlayGuiObjectController::Update(dt); + GameObserver * game = GameObserver::GetInstance(); +} + + + +void MTGGuiPlay::CheckUserInput(float dt){ + for (int i = 2; i<6;i++){ + GuiGameZone * zone = (GuiGameZone *)mObjects[i]; + if (zone->showCards){ + zone->cd->CheckUserInput(dt); + return; + } + } + PlayGuiObjectController::CheckUserInput(dt); + + +} + + +void MTGGuiPlay::RenderPlayerInfo(int playerid){ + GameObserver * game = GameObserver::GetInstance(); + JRenderer * r = JRenderer::GetInstance(); + Player * player = GameObserver::GetInstance()->players[playerid]; + int life = player->life; + + //Avatar + GuiAvatar * avatar = (GuiAvatar *)mObjects[3*playerid]; + avatar->Render(); + + + + //Mana + ManaCost * cost = player->getManaPool(); + int nbicons = 0; + for (int j=0; j<6;j++){ + int value = cost->getCost(j); + for (int i=0; iRenderQuad(mIcons[j],x,y,0,0.5, 0.5); + nbicons++; + } + } +} + + +void MTGGuiPlay::RenderPhaseBar(){ + GameObserver * game = GameObserver::GetInstance(); + JRenderer * renderer = JRenderer::GetInstance(); + int currentPhase = game->getCurrentGamePhase(); + for (int i=0; i < 12; i++){ + int index = 2*i + 1 ; + if (i==currentPhase-1){ + index-=1; + } + renderer->RenderQuad(phaseIcons[index], 200 + 14*i,0,0,0.5,0.5); + } + mFont->SetScale(0.70); + if (game->currentlyActing()->isAI()){ + mFont->SetColor(ARGB(255,128,128,128)); + }else{ + mFont->SetColor(ARGB(255,255,255,255)); + } + mFont->DrawString(MTGPhaseNames[currentPhase], 375, 0); +} + +void MTGGuiPlay::Render(){ + JRenderer * renderer = JRenderer::GetInstance(); + + //alphaBg[1] = 255; + //alphaBg[2]= 255; + //alphaBg[3] = 255; + //mBg2->SetColor(ARGB(alphaBg[0], alphaBg[1],alphaBg[2],alphaBg[3])); + renderer->RenderQuad(mBg2,0,17); + + if (game->currentGamePhase >=MTG_PHASE_COMBATBEGIN && game->currentGamePhase < MTG_PHASE_COMBATEND){ + if (alphaBg[0] < 50){ + alphaBg[3]-=12; + alphaBg[2]-=12; + alphaBg[0]+=3; + } + alphaBg[1] = 255; + + }else{ + if (alphaBg[0]){ + alphaBg[0]-=3; + alphaBg[3]+=12; + alphaBg[2]+=12; + } + alphaBg[1] = 255; + } + renderer->FillRect(0,0,480,272,ARGB(alphaBg[0], alphaBg[1],alphaBg[2],alphaBg[3])); + + renderer->RenderQuad(mBg,0,0); + + for (int i=0;iRender(); + } + } + + RenderPhaseBar(); + RenderPlayerInfo(0); + RenderPlayerInfo(1); + + if (mCount && mObjects[mCurr] != NULL){ + mObjects[mCurr]->Render(); + if (hasFocus && mCurr >= offset && showBigCards) + ((CardGui *)mObjects[mCurr])->RenderBig(); + } + + if (mGlitterAlpha < 0){ + mGlitterAlpha = 510; + int position = rand() % 2; + if (position){ + mGlitterX = 65 + rand() % (420); + mGlitterY = 17 + rand() % (5); + }else{ + mGlitterX = 65 + rand() % (5); + mGlitterY = 15 + rand() % (250); + } + } + mGlitter->SetColor(ARGB((255-abs(255-mGlitterAlpha)),240,240,255)); + renderer->RenderQuad(mGlitter,mGlitterX,mGlitterY, (float)(mGlitterAlpha)/(float)255, 1.2*float(mGlitterAlpha)/float(255),1.2*float(mGlitterAlpha)/float(255)); + mGlitterAlpha-=10; + +} + +MTGGuiPlay::~MTGGuiPlay(){ + LOG("==Destroying MTGGuiPlay=="); + delete mBg; + delete mBgTex; + for (int i=0; i < 7; i++){ + delete mIcons[i]; + } + delete mIconsTexture; + delete mGlitter; + for (int i=0; i < 12; i++){ + delete phaseIcons[2*i] ; + delete phaseIcons[2*i + 1]; + } + delete mPhaseBarTexture; + + SAFE_DELETE(mBg2); + SAFE_DELETE(mBgTex2); + + LOG("==Destroying MTGGuiPlay Successful=="); + +} diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index 55735b91f..da8e64018 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -1,60 +1,60 @@ -#include "../include/debug.h" -#include "../include/MTGRules.h" - -MTGAttackRule::MTGAttackRule(int _id):MTGAbility(_id,NULL){ -} - -int MTGAttackRule::isReactingToClick(MTGCardInstance * card){ - if (currentPhase == MTG_PHASE_COMBATATTACKERS && card->controller() == game->currentPlayer && !card->isAttacker()){ - if (card->canAttack()) return 1; - } - return 0; -} - -int MTGAttackRule::reactToClick(MTGCardInstance * card){ - if (!isReactingToClick(card)) return 0; - card->attacker = 1; - if (!card->basicAbilities[VIGILANCE]) card->tapped = 1; - return 1; -} - -//The Attack rule is never destroyed -int MTGAttackRule::testDestroy(){ - return 0; -} - - - -MTGBlockRule::MTGBlockRule(int _id):MTGAbility(_id,NULL){ -} - -int MTGBlockRule::isReactingToClick(MTGCardInstance * card){ - if (currentPhase == MTG_PHASE_COMBATBLOCKERS && !game->isInterrupting && card->controller() == game->opponent()){ - if (card->canBlock()) return 1; - } - return 0; -} - -int MTGBlockRule::reactToClick(MTGCardInstance * card){ - if (!isReactingToClick(card)) return 0; - MTGCardInstance * currentOpponent = card->isDefenser(); - - bool result = false; - int candefend = 0; - while (!result){ - currentOpponent = game->currentPlayer->game->inPlay->getNextAttacker(currentOpponent); - #if defined (WIN32) || defined (LINUX) - char buf[4096]; - sprintf(buf,"Defenser Toggle %s \n" ,card->model->getName()); - OutputDebugString(buf); - #endif - candefend = card->toggleDefenser(currentOpponent); - result = (candefend || currentOpponent == NULL); - } - return 1; -} - -//The Block rule is never destroyed -int MTGBlockRule::testDestroy(){ - return 0; -} \ No newline at end of file +#include "../include/debug.h" +#include "../include/MTGRules.h" + +MTGAttackRule::MTGAttackRule(int _id):MTGAbility(_id,NULL){ +} + +int MTGAttackRule::isReactingToClick(MTGCardInstance * card){ + if (currentPhase == MTG_PHASE_COMBATATTACKERS && card->controller() == game->currentPlayer && !card->isAttacker()){ + if (card->canAttack()) return 1; + } + return 0; +} + +int MTGAttackRule::reactToClick(MTGCardInstance * card){ + if (!isReactingToClick(card)) return 0; + card->attacker = 1; + if (!card->basicAbilities[VIGILANCE]) card->tapped = 1; + return 1; +} + +//The Attack rule is never destroyed +int MTGAttackRule::testDestroy(){ + return 0; +} + + + +MTGBlockRule::MTGBlockRule(int _id):MTGAbility(_id,NULL){ +} + +int MTGBlockRule::isReactingToClick(MTGCardInstance * card){ + if (currentPhase == MTG_PHASE_COMBATBLOCKERS && !game->isInterrupting && card->controller() == game->opponent()){ + if (card->canBlock()) return 1; + } + return 0; +} + +int MTGBlockRule::reactToClick(MTGCardInstance * card){ + if (!isReactingToClick(card)) return 0; + MTGCardInstance * currentOpponent = card->isDefenser(); + + bool result = false; + int candefend = 0; + while (!result){ + currentOpponent = game->currentPlayer->game->inPlay->getNextAttacker(currentOpponent); +#if defined (WIN32) || defined (LINUX) + char buf[4096]; + sprintf(buf,"Defenser Toggle %s \n" ,card->model->getName()); + OutputDebugString(buf); +#endif + candefend = card->toggleDefenser(currentOpponent); + result = (candefend || currentOpponent == NULL); + } + return 1; +} + +//The Block rule is never destroyed +int MTGBlockRule::testDestroy(){ + return 0; +} diff --git a/projects/mtg/src/MTGSpellStack.cpp b/projects/mtg/src/MTGSpellStack.cpp index c2f568718..c4f10a92a 100644 --- a/projects/mtg/src/MTGSpellStack.cpp +++ b/projects/mtg/src/MTGSpellStack.cpp @@ -10,7 +10,7 @@ void MTGSpellStack::addSpell(Ability * ability){ } int MTGSpellStack::resolve(){ - if (cursor < 0) + if (cursor < 0) return 0; int result = cursor; cursor--; diff --git a/projects/mtg/src/ManaCost.cpp b/projects/mtg/src/ManaCost.cpp index 5676fb78e..1b5fbb14b 100644 --- a/projects/mtg/src/ManaCost.cpp +++ b/projects/mtg/src/ManaCost.cpp @@ -1,320 +1,320 @@ -#include "../include/debug.h" -#include "../include/Logger.h" -#include "../include/ManaCost.h" -#include "../include/ManaCostHybrid.h" - -#if defined (WIN32) - - #include -#endif - -ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost){ -#if defined (WIN32) || defined (LINUX) -char buf[4096]; -#endif - ManaCost * manaCost; - if (_manaCost){ - manaCost = _manaCost; - }else{ - manaCost = NEW ManaCost(); - } - int state = 0; - unsigned int start = 0; - unsigned int end = 0; - while (!s.empty() && state != -1){ - switch(state){ - case 0: - start = s.find_first_of("{"); - if (start == string::npos){ - return manaCost; - }else{ - state = 1; - } - break; - case 1: - end = s.find_first_of("}"); - if (end == string::npos){ - state = -1; - }else{ - string value = s.substr(start+1, end - 1 - start); - if (value == "u"){ - manaCost->add(MTG_COLOR_BLUE, 1); - }else if (value == "b"){ - manaCost->add(MTG_COLOR_BLACK, 1); - }else if (value == "w"){ - manaCost->add(MTG_COLOR_WHITE, 1); - }else if (value == "g"){ - manaCost->add(MTG_COLOR_GREEN, 1); - }else if (value == "r"){ - manaCost->add(MTG_COLOR_RED, 1); - }else if (value == "x"){ - manaCost->x(); - }else if (value == "t"){ - }else{ - int intvalue = atoi(value.c_str()); - int colors[2]; - int values[2]; - if (!intvalue && value.size() > 1){ -#if defined (WIN32) || defined (LINUX) -OutputDebugString("Hybrid Mana ???\n"); -#endif - for (int i = 0; i < 2; i++){ - char c = value[i]; - if (c >='0' && c <='9'){ - colors[i] = MTG_COLOR_ARTIFACT; - values[i] = c - '0'; - }else{ - for (int j = 0; j < MTG_NB_COLORS; j++){ - if (c == MTGColorChars[j]){ - colors[i] = j; - values[i] = 1; - } - } - } - } - manaCost->addHybrid(colors[0], values[0], colors[1], values[1]); - }else{ - manaCost->add(MTG_COLOR_ARTIFACT, intvalue); - } - } - s = s.substr(end + 1); - state = 0; - } - break; - default: - break; - } - } - return manaCost; -} - -ManaCost::ManaCost(){ - init(); -} -ManaCost::ManaCost(int _cost[], int nb_elems){ - init(); - int i; - int total = nb_elems; -#if defined (WIN32) || defined (LINUX) -char buf[4096]; -sprintf(buf, "Create New MAnaCost, total Colors : %i\n", total); -OutputDebugString(buf); -#endif - for (i = 0; i < total; i++){ - cost[_cost[i*2]] = _cost[i*2 + 1]; - } - -} - -ManaCost::ManaCost(ManaCost * _manaCost){ - init(); - int i; - for (i=0; i<= MTG_NB_COLORS; i++){ - cost[i] = _manaCost->getCost(i); - } -} - -ManaCost::~ManaCost(){ - LOG("==Deleting ManaCost=="); - for (int i = 0; i < nbhybrids ; i++){ - SAFE_DELETE(hybrids[i]); - } -} - -void ManaCost::x(){ - cost[MTG_NB_COLORS] = 1; -} - -void ManaCost::init(){ - int i; - for (i=0; i<= MTG_NB_COLORS; i++){ - cost[i] = 0; - } - nbhybrids = 0; -} - - -void ManaCost::copy(ManaCost * _manaCost){ - for (int i=0; i<= MTG_NB_COLORS; i++){ - cost[i] = _manaCost->getCost(i); - } - for (int i=0; i< _manaCost->nbhybrids; i++){ - hybrids[i] = NEW ManaCostHybrid((*_manaCost->hybrids[i])); - } - nbhybrids = _manaCost->nbhybrids; -} - -int ManaCost::getCost(int color){ - return cost[color]; -} - -int ManaCost::getMainColor(){ - for (int i=0; i< MTG_NB_COLORS; i++){ - if (cost[i]) return i; - } - return 0; -} - -int ManaCost::hasColor(int color){ - if (cost[color]) return 1; - for (int i = 0; i < nbhybrids; i++){ - if (hybrids[i]->hasColor(color)) return 1; - } - return 0; -} - -int ManaCost::getConvertedCost(){ - int result = 0; - for (int i=0; i< MTG_NB_COLORS; i++){ - result += cost[i]; - } - for (int i = 0; i < nbhybrids; i++){ - result+= hybrids[i]->getConvertedCost(); - } - return result; -} - -int ManaCost::remove(int color, int value){ - cost[color] -= value; - return 1; -} - -int ManaCost::add(int color, int value){ - cost[color] += value; - return 1; -} - -int ManaCost::add(ManaCost * _cost){ - for (int i=0; i< MTG_NB_COLORS; i++){ - cost[i]+= _cost->getCost(i); - } - for (int i=0; i< _cost->nbhybrids; i++){ - hybrids[nbhybrids] = NEW ManaCostHybrid((*_cost->hybrids[i])); - nbhybrids++; - } - return 1; -} - -string ManaCost::toString(){ - return "ManaCost - Todo"; -} - - -int ManaCost::addHybrid(int c1, int v1, int c2, int v2){ - ManaCostHybrid * h = NEW ManaCostHybrid(c1,v1,c2,v2); - hybrids[nbhybrids] = h; - nbhybrids++; - return nbhybrids; -} - -int ManaCost::pay(ManaCost * _cost){ - ManaCost * diff = Diff(_cost); - for (int i=0; i < MTG_NB_COLORS; i++){ - cost[i] = diff->getCost(i); - } - delete diff; - return 1; - //TODO return 0 if can't afford the cost! -} - -//return 1 if _cost can be paid with current data -int ManaCost::canAfford(ManaCost * _cost){ - ManaCost * diff = Diff(_cost); - int positive = diff->isPositive(); - delete diff; - if (positive){ -#if defined (WIN32) || defined (LINUX) - OutputDebugString("can afford\n"); -#endif - return 1; - } - return 0; -} - -int ManaCost::isPositive(){ - for (int i=0; i < MTG_NB_COLORS; i++){ - - if (cost[i] < 0){ - return 0; - } - } - return 1; - -} - - -void ManaCost::randomDiffHybrids(ManaCost * _cost, int diff[]){ - int _nbhybrids = _cost->nbhybrids; - for (int i = 0; i < _nbhybrids; i++){ - ManaCostHybrid * h = _cost->hybrids[i]; - diff[h->color1 * 2 +1]-= h->value1; - } -} - -int ManaCost::tryToPayHybrids(ManaCostHybrid * _hybrids[], int _nbhybrids, int diff[]){ - if (!_nbhybrids) return 1; - int result = 0; - ManaCostHybrid * h = _hybrids[_nbhybrids -1]; - if (diff[h->color1 * 2 +1] >= h->value1){ - diff[h->color1 * 2 +1]-= h->value1; - result = tryToPayHybrids(_hybrids,_nbhybrids -1, diff); - if (result) return 1; - diff[h->color1 * 2 +1]+= h->value1; - } - if (diff[h->color2 * 2 +1] >= h->value2){ - diff[h->color2 * 2 +1]-= h->value2; - result = tryToPayHybrids(_hybrids,_nbhybrids -1, diff); - if (result) return 1; - diff[h->color2 * 2 +1]+= h->value2; - } - return 0; -} - -//compute the difference between two mana costs -ManaCost * ManaCost::Diff(ManaCost * _cost){ - int diff[(MTG_NB_COLORS + 1 )* 2]; - diff[MTG_NB_COLORS * 2] = MTG_NB_COLORS; - for (int i=0; i < MTG_NB_COLORS; i++){ - diff[i*2] = i; - diff[i*2 +1] = cost[i] - _cost->getCost(i); - } - int hybridResult = tryToPayHybrids(_cost->hybrids, _cost->nbhybrids, diff); - if (!hybridResult) randomDiffHybrids(_cost,diff); - - //Colorless mana, special case - int colorless_idx = MTG_COLOR_ARTIFACT * 2 + 1; - if (diff[colorless_idx] < 0){ -#if defined (WIN32) || defined (LINUX) -//char buf[4096], *p = buf; -//sprintf(buf, "--Diff color TEST %i : %i\n", i, cost[i]); -OutputDebugString("Colorless mana not enough\n"); -#endif - for (int i=0; i < MTG_NB_COLORS; i++){ - if (diff[i*2 + 1] > 0){ - if (diff[i*2 + 1] + diff[colorless_idx] > 0){ - diff[i*2 + 1] += diff[colorless_idx]; - diff[colorless_idx] = 0; - break; - }else{ - diff[colorless_idx] += diff[i*2 + 1]; - diff[i*2 + 1] = 0; - } - } - } - } - - //Cost X - if (_cost->getCost(MTG_NB_COLORS)){ - diff[MTG_NB_COLORS * 2 + 1] = 0; - for (int i=0; i < MTG_NB_COLORS; i++){ - if (diff[i*2 + 1] > 0){ - diff[MTG_NB_COLORS * 2 + 1] += diff[i*2 + 1]; - diff[i*2 + 1] = 0; - } - } - } - - ManaCost * result = NEW ManaCost(diff, MTG_NB_COLORS +1); - return result; - -} +#include "../include/debug.h" +#include "../include/Logger.h" +#include "../include/ManaCost.h" +#include "../include/ManaCostHybrid.h" + +#if defined (WIN32) + +#include +#endif + +ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost){ +#if defined (WIN32) || defined (LINUX) + char buf[4096]; +#endif + ManaCost * manaCost; + if (_manaCost){ + manaCost = _manaCost; + }else{ + manaCost = NEW ManaCost(); + } + int state = 0; + unsigned int start = 0; + unsigned int end = 0; + while (!s.empty() && state != -1){ + switch(state){ + case 0: + start = s.find_first_of("{"); + if (start == string::npos){ + return manaCost; + }else{ + state = 1; + } + break; + case 1: + end = s.find_first_of("}"); + if (end == string::npos){ + state = -1; + }else{ + string value = s.substr(start+1, end - 1 - start); + if (value == "u"){ + manaCost->add(MTG_COLOR_BLUE, 1); + }else if (value == "b"){ + manaCost->add(MTG_COLOR_BLACK, 1); + }else if (value == "w"){ + manaCost->add(MTG_COLOR_WHITE, 1); + }else if (value == "g"){ + manaCost->add(MTG_COLOR_GREEN, 1); + }else if (value == "r"){ + manaCost->add(MTG_COLOR_RED, 1); + }else if (value == "x"){ + manaCost->x(); + }else if (value == "t"){ + }else{ + int intvalue = atoi(value.c_str()); + int colors[2]; + int values[2]; + if (!intvalue && value.size() > 1){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("Hybrid Mana ???\n"); +#endif + for (int i = 0; i < 2; i++){ + char c = value[i]; + if (c >='0' && c <='9'){ + colors[i] = MTG_COLOR_ARTIFACT; + values[i] = c - '0'; + }else{ + for (int j = 0; j < MTG_NB_COLORS; j++){ + if (c == MTGColorChars[j]){ + colors[i] = j; + values[i] = 1; + } + } + } + } + manaCost->addHybrid(colors[0], values[0], colors[1], values[1]); + }else{ + manaCost->add(MTG_COLOR_ARTIFACT, intvalue); + } + } + s = s.substr(end + 1); + state = 0; + } + break; + default: + break; + } + } + return manaCost; +} + +ManaCost::ManaCost(){ + init(); +} +ManaCost::ManaCost(int _cost[], int nb_elems){ + init(); + int i; + int total = nb_elems; +#if defined (WIN32) || defined (LINUX) + char buf[4096]; + sprintf(buf, "Create New MAnaCost, total Colors : %i\n", total); + OutputDebugString(buf); +#endif + for (i = 0; i < total; i++){ + cost[_cost[i*2]] = _cost[i*2 + 1]; + } + +} + +ManaCost::ManaCost(ManaCost * _manaCost){ + init(); + int i; + for (i=0; i<= MTG_NB_COLORS; i++){ + cost[i] = _manaCost->getCost(i); + } +} + +ManaCost::~ManaCost(){ + LOG("==Deleting ManaCost=="); + for (int i = 0; i < nbhybrids ; i++){ + SAFE_DELETE(hybrids[i]); + } +} + +void ManaCost::x(){ + cost[MTG_NB_COLORS] = 1; +} + +void ManaCost::init(){ + int i; + for (i=0; i<= MTG_NB_COLORS; i++){ + cost[i] = 0; + } + nbhybrids = 0; +} + + +void ManaCost::copy(ManaCost * _manaCost){ + for (int i=0; i<= MTG_NB_COLORS; i++){ + cost[i] = _manaCost->getCost(i); + } + for (int i=0; i< _manaCost->nbhybrids; i++){ + hybrids[i] = NEW ManaCostHybrid((*_manaCost->hybrids[i])); + } + nbhybrids = _manaCost->nbhybrids; +} + +int ManaCost::getCost(int color){ + return cost[color]; +} + +int ManaCost::getMainColor(){ + for (int i=0; i< MTG_NB_COLORS; i++){ + if (cost[i]) return i; + } + return 0; +} + +int ManaCost::hasColor(int color){ + if (cost[color]) return 1; + for (int i = 0; i < nbhybrids; i++){ + if (hybrids[i]->hasColor(color)) return 1; + } + return 0; +} + +int ManaCost::getConvertedCost(){ + int result = 0; + for (int i=0; i< MTG_NB_COLORS; i++){ + result += cost[i]; + } + for (int i = 0; i < nbhybrids; i++){ + result+= hybrids[i]->getConvertedCost(); + } + return result; +} + +int ManaCost::remove(int color, int value){ + cost[color] -= value; + return 1; +} + +int ManaCost::add(int color, int value){ + cost[color] += value; + return 1; +} + +int ManaCost::add(ManaCost * _cost){ + for (int i=0; i< MTG_NB_COLORS; i++){ + cost[i]+= _cost->getCost(i); + } + for (int i=0; i< _cost->nbhybrids; i++){ + hybrids[nbhybrids] = NEW ManaCostHybrid((*_cost->hybrids[i])); + nbhybrids++; + } + return 1; +} + +string ManaCost::toString(){ + return "ManaCost - Todo"; +} + + +int ManaCost::addHybrid(int c1, int v1, int c2, int v2){ + ManaCostHybrid * h = NEW ManaCostHybrid(c1,v1,c2,v2); + hybrids[nbhybrids] = h; + nbhybrids++; + return nbhybrids; +} + +int ManaCost::pay(ManaCost * _cost){ + ManaCost * diff = Diff(_cost); + for (int i=0; i < MTG_NB_COLORS; i++){ + cost[i] = diff->getCost(i); + } + delete diff; + return 1; + //TODO return 0 if can't afford the cost! +} + +//return 1 if _cost can be paid with current data +int ManaCost::canAfford(ManaCost * _cost){ + ManaCost * diff = Diff(_cost); + int positive = diff->isPositive(); + delete diff; + if (positive){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("can afford\n"); +#endif + return 1; + } + return 0; +} + +int ManaCost::isPositive(){ + for (int i=0; i < MTG_NB_COLORS; i++){ + + if (cost[i] < 0){ + return 0; + } + } + return 1; + +} + + +void ManaCost::randomDiffHybrids(ManaCost * _cost, int diff[]){ + int _nbhybrids = _cost->nbhybrids; + for (int i = 0; i < _nbhybrids; i++){ + ManaCostHybrid * h = _cost->hybrids[i]; + diff[h->color1 * 2 +1]-= h->value1; + } +} + +int ManaCost::tryToPayHybrids(ManaCostHybrid * _hybrids[], int _nbhybrids, int diff[]){ + if (!_nbhybrids) return 1; + int result = 0; + ManaCostHybrid * h = _hybrids[_nbhybrids -1]; + if (diff[h->color1 * 2 +1] >= h->value1){ + diff[h->color1 * 2 +1]-= h->value1; + result = tryToPayHybrids(_hybrids,_nbhybrids -1, diff); + if (result) return 1; + diff[h->color1 * 2 +1]+= h->value1; + } + if (diff[h->color2 * 2 +1] >= h->value2){ + diff[h->color2 * 2 +1]-= h->value2; + result = tryToPayHybrids(_hybrids,_nbhybrids -1, diff); + if (result) return 1; + diff[h->color2 * 2 +1]+= h->value2; + } + return 0; +} + +//compute the difference between two mana costs +ManaCost * ManaCost::Diff(ManaCost * _cost){ + int diff[(MTG_NB_COLORS + 1 )* 2]; + diff[MTG_NB_COLORS * 2] = MTG_NB_COLORS; + for (int i=0; i < MTG_NB_COLORS; i++){ + diff[i*2] = i; + diff[i*2 +1] = cost[i] - _cost->getCost(i); + } + int hybridResult = tryToPayHybrids(_cost->hybrids, _cost->nbhybrids, diff); + if (!hybridResult) randomDiffHybrids(_cost,diff); + + //Colorless mana, special case + int colorless_idx = MTG_COLOR_ARTIFACT * 2 + 1; + if (diff[colorless_idx] < 0){ +#if defined (WIN32) || defined (LINUX) + //char buf[4096], *p = buf; + //sprintf(buf, "--Diff color TEST %i : %i\n", i, cost[i]); + OutputDebugString("Colorless mana not enough\n"); +#endif + for (int i=0; i < MTG_NB_COLORS; i++){ + if (diff[i*2 + 1] > 0){ + if (diff[i*2 + 1] + diff[colorless_idx] > 0){ + diff[i*2 + 1] += diff[colorless_idx]; + diff[colorless_idx] = 0; + break; + }else{ + diff[colorless_idx] += diff[i*2 + 1]; + diff[i*2 + 1] = 0; + } + } + } + } + + //Cost X + if (_cost->getCost(MTG_NB_COLORS)){ + diff[MTG_NB_COLORS * 2 + 1] = 0; + for (int i=0; i < MTG_NB_COLORS; i++){ + if (diff[i*2 + 1] > 0){ + diff[MTG_NB_COLORS * 2 + 1] += diff[i*2 + 1]; + diff[i*2 + 1] = 0; + } + } + } + + ManaCost * result = NEW ManaCost(diff, MTG_NB_COLORS +1); + return result; + +} diff --git a/projects/mtg/src/ManaCostHybrid.cpp b/projects/mtg/src/ManaCostHybrid.cpp index 609c8c0e4..d674adf4f 100644 --- a/projects/mtg/src/ManaCostHybrid.cpp +++ b/projects/mtg/src/ManaCostHybrid.cpp @@ -1,26 +1,26 @@ -#include "../include/ManaCostHybrid.h" - -ManaCostHybrid::ManaCostHybrid(){ - init(0,0,0,0); -} - -ManaCostHybrid::ManaCostHybrid(int c1,int v1,int c2,int v2){ - init(c1,v1,c2,v2); -} - -void ManaCostHybrid::init(int c1,int v1,int c2,int v2){ - color1 = c1; - color2 = c2; - value1 = v1; - value2 = v2; -} - -int ManaCostHybrid::getConvertedCost(){ - if (value2 > value1) return value2; - return value1; -} - -int ManaCostHybrid::hasColor(int color){ - if (((color1 == color) && value1) || ((color2 == color) && value2)) return 1; - return 0; -} \ No newline at end of file +#include "../include/ManaCostHybrid.h" + +ManaCostHybrid::ManaCostHybrid(){ + init(0,0,0,0); +} + +ManaCostHybrid::ManaCostHybrid(int c1,int v1,int c2,int v2){ + init(c1,v1,c2,v2); +} + +void ManaCostHybrid::init(int c1,int v1,int c2,int v2){ + color1 = c1; + color2 = c2; + value1 = v1; + value2 = v2; +} + +int ManaCostHybrid::getConvertedCost(){ + if (value2 > value1) return value2; + return value1; +} + +int ManaCostHybrid::hasColor(int color){ + if (((color1 == color) && value1) || ((color2 == color) && value2)) return 1; + return 0; +} diff --git a/projects/mtg/src/MenuItem.cpp b/projects/mtg/src/MenuItem.cpp index 21066eb09..6b57049a2 100644 --- a/projects/mtg/src/MenuItem.cpp +++ b/projects/mtg/src/MenuItem.cpp @@ -1,113 +1,113 @@ -#include "../include/debug.h" -#include "../include/MenuItem.h" - - -MenuItem::MenuItem(int id, JLBFont *font, const char* text, int x, int y, JQuad * _off, JQuad * _on, const char * particle, JQuad * particleTex, bool hasFocus): JGuiObject(id), mFont(font), mText(text), mX(x), mY(y) -{ - - - - updatedSinceLastRender = 1; - mParticleSys = NEW hgeParticleSystem(particle, particleTex); - mParticleSys->MoveTo(mX, mY); - - - mHasFocus = hasFocus; - lastDt = 0.001f; - mScale = 1.0f; - mTargetScale = 1.0f; - - onQuad = _on; - offQuad = _off; - - if (hasFocus) - Entering(); - mFont->SetScale(1.2f); - -} - - -void MenuItem::Render() -{ - - JRenderer * renderer = JRenderer::GetInstance(); - - - if (mHasFocus) - { - if (!updatedSinceLastRender){ - mParticleSys->Update(lastDt); - } - // set additive blending - renderer->SetTexBlend(BLEND_SRC_ALPHA, BLEND_ONE); - mParticleSys->Render(); - // set normal blending - renderer->SetTexBlend(BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA); - mFont->SetColor(ARGB(255,255,255,255)); - onQuad->SetColor(ARGB(70,255,255,255)); - renderer->RenderQuad(onQuad, SCREEN_WIDTH , SCREEN_HEIGHT/2 , 0,8,8); - onQuad->SetColor(ARGB(255,255,255,255)); - mFont->DrawString(mText, SCREEN_WIDTH/2, 3*SCREEN_HEIGHT/4, JGETEXT_CENTER); - renderer->RenderQuad(onQuad, mX , mY , 0,mScale,mScale); - - } - else - { - renderer->RenderQuad(offQuad, mX , mY , 0,mScale,mScale); - } - updatedSinceLastRender= 0; -} - -void MenuItem::Update(float dt) -{ - updatedSinceLastRender = 1; - lastDt = dt; - if (mScale < mTargetScale) - { - mScale += 8.0f*dt; - if (mScale > mTargetScale) - mScale = mTargetScale; - } - else if (mScale > mTargetScale) - { - mScale -= 8.0f*dt; - if (mScale < mTargetScale) - mScale = mTargetScale; - } - - if (mHasFocus){ - mParticleSys->Update(dt); - } - -} - - - - -void MenuItem::Entering() -{ - - mParticleSys->Fire(); - mHasFocus = true; - mTargetScale = 1.3f; -} - - -bool MenuItem::Leaving(u32 key) -{ - mParticleSys->Stop(true); - mHasFocus = false; - mTargetScale = 1.0f; - return true; -} - - -bool MenuItem::ButtonPressed() -{ - return true; -} - - -MenuItem::~MenuItem(){ - if (mParticleSys) delete mParticleSys; -} +#include "../include/debug.h" +#include "../include/MenuItem.h" + + +MenuItem::MenuItem(int id, JLBFont *font, const char* text, int x, int y, JQuad * _off, JQuad * _on, const char * particle, JQuad * particleTex, bool hasFocus): JGuiObject(id), mFont(font), mText(text), mX(x), mY(y) +{ + + + + updatedSinceLastRender = 1; + mParticleSys = NEW hgeParticleSystem(particle, particleTex); + mParticleSys->MoveTo(mX, mY); + + + mHasFocus = hasFocus; + lastDt = 0.001f; + mScale = 1.0f; + mTargetScale = 1.0f; + + onQuad = _on; + offQuad = _off; + + if (hasFocus) + Entering(); + mFont->SetScale(1.2f); + +} + + +void MenuItem::Render() +{ + + JRenderer * renderer = JRenderer::GetInstance(); + + + if (mHasFocus) + { + if (!updatedSinceLastRender){ + mParticleSys->Update(lastDt); + } + // set additive blending + renderer->SetTexBlend(BLEND_SRC_ALPHA, BLEND_ONE); + mParticleSys->Render(); + // set normal blending + renderer->SetTexBlend(BLEND_SRC_ALPHA, BLEND_ONE_MINUS_SRC_ALPHA); + mFont->SetColor(ARGB(255,255,255,255)); + onQuad->SetColor(ARGB(70,255,255,255)); + renderer->RenderQuad(onQuad, SCREEN_WIDTH , SCREEN_HEIGHT/2 , 0,8,8); + onQuad->SetColor(ARGB(255,255,255,255)); + mFont->DrawString(mText, SCREEN_WIDTH/2, 3*SCREEN_HEIGHT/4, JGETEXT_CENTER); + renderer->RenderQuad(onQuad, mX , mY , 0,mScale,mScale); + + } + else + { + renderer->RenderQuad(offQuad, mX , mY , 0,mScale,mScale); + } + updatedSinceLastRender= 0; +} + +void MenuItem::Update(float dt) +{ + updatedSinceLastRender = 1; + lastDt = dt; + if (mScale < mTargetScale) + { + mScale += 8.0f*dt; + if (mScale > mTargetScale) + mScale = mTargetScale; + } + else if (mScale > mTargetScale) + { + mScale -= 8.0f*dt; + if (mScale < mTargetScale) + mScale = mTargetScale; + } + + if (mHasFocus){ + mParticleSys->Update(dt); + } + +} + + + + +void MenuItem::Entering() +{ + + mParticleSys->Fire(); + mHasFocus = true; + mTargetScale = 1.3f; +} + + +bool MenuItem::Leaving(u32 key) +{ + mParticleSys->Stop(true); + mHasFocus = false; + mTargetScale = 1.0f; + return true; +} + + +bool MenuItem::ButtonPressed() +{ + return true; +} + + +MenuItem::~MenuItem(){ + if (mParticleSys) delete mParticleSys; +} diff --git a/projects/mtg/src/OptionItem.cpp b/projects/mtg/src/OptionItem.cpp index a19d8ca1c..4ca1a8651 100644 --- a/projects/mtg/src/OptionItem.cpp +++ b/projects/mtg/src/OptionItem.cpp @@ -1,120 +1,120 @@ -#include "../include/OptionItem.h" -#include "../include/GameApp.h" -#include -#include "../include/GameOptions.h" - - - OptionItem::OptionItem(int _id, string _displayValue, int _maxValue, int _increment):JGuiObject(0){ - id = _id; - maxValue = _maxValue; - increment = _increment; - displayValue = _displayValue; - value = GameOptions::GetInstance()->values[id]; - hasFocus = 0; - x = 0; - y = 0; - } - - OptionItem::~OptionItem(){ - //TODO - } - - void OptionItem::setData(){ - GameOptions::GetInstance()->values[id] = value; - } - - void OptionItem::Render(){ - JLBFont * mFont = GameApp::CommonRes->GetJLBFont("graphics/f3"); - if (hasFocus){ - mFont->SetColor(ARGB(255,255,255,0)); - }else{ - mFont->SetColor(ARGB(255,255,255,255)); - } - JRenderer * renderer = JRenderer::GetInstance(); - mFont->DrawString(displayValue.c_str(),x,y); - char buf[512]; - sprintf(buf, "%i", value); - mFont->DrawString(buf,SCREEN_WIDTH -10 ,y,JGETEXT_RIGHT); - } - - void OptionItem::Update(float dt){ - JGE * mEngine = JGE::GetInstance(); - if (hasFocus){ - if (mEngine->GetButtonClick(PSP_CTRL_CIRCLE)) updateValue(); - } - } - - void OptionItem::Entering(){ - hasFocus = true; - } - bool OptionItem::Leaving(){ - hasFocus = false; - return true; - } - - - OptionItem * options[20]; - int nbitems; - OptionsList::OptionsList(){ - nbitems = 0; - current = -1; - } - OptionsList::~OptionsList(){ - for (int i = 0 ; i < nbitems; i++){ - SAFE_DELETE(options[i]); - } - } - - void OptionsList::Add(OptionItem * item){ - if (nbitems < 20){ - options[nbitems] = item; - item->x = 10; - item->y = 20 + 30*nbitems; - nbitems++; - if (current < 0){ - current = 0; - options[0]->Entering(); - } - - } - } - - void OptionsList::Render(){ - if (!nbitems){ - JLBFont * mFont = GameApp::CommonRes->GetJLBFont("graphics/f3"); - mFont->DrawString("NO OPTIONS AVAILABLE",SCREEN_WIDTH/2, 5, JGETEXT_RIGHT); - } - for (int i = 0 ; i < nbitems; i++){ - options[i]->Render(); - } - } - - void OptionsList::save(){ - for (int i = 0; i < nbitems; i++){ - options[i]->setData(); - } - GameOptions::GetInstance()->save(); - } - - void OptionsList::Update(float dt){ - JGE * mEngine = JGE::GetInstance(); - if (mEngine->GetButtonClick(PSP_CTRL_UP)) - { - if (current > 0){ - options[current]->Leaving(); - current--; - options[current]->Entering(); - } - } - else if (mEngine->GetButtonClick(PSP_CTRL_DOWN)) - { - if (current < nbitems -1){ - options[current]->Leaving(); - current++; - options[current]->Entering(); - } - } - for (int i = 0 ; i < nbitems; i++){ - options[i]->Update(dt); - } -} +#include "../include/OptionItem.h" +#include "../include/GameApp.h" +#include +#include "../include/GameOptions.h" + + +OptionItem::OptionItem(int _id, string _displayValue, int _maxValue, int _increment):JGuiObject(0){ + id = _id; + maxValue = _maxValue; + increment = _increment; + displayValue = _displayValue; + value = GameOptions::GetInstance()->values[id]; + hasFocus = 0; + x = 0; + y = 0; +} + +OptionItem::~OptionItem(){ + //TODO +} + +void OptionItem::setData(){ + GameOptions::GetInstance()->values[id] = value; +} + +void OptionItem::Render(){ + JLBFont * mFont = GameApp::CommonRes->GetJLBFont("graphics/f3"); + if (hasFocus){ + mFont->SetColor(ARGB(255,255,255,0)); + }else{ + mFont->SetColor(ARGB(255,255,255,255)); + } + JRenderer * renderer = JRenderer::GetInstance(); + mFont->DrawString(displayValue.c_str(),x,y); + char buf[512]; + sprintf(buf, "%i", value); + mFont->DrawString(buf,SCREEN_WIDTH -10 ,y,JGETEXT_RIGHT); +} + +void OptionItem::Update(float dt){ + JGE * mEngine = JGE::GetInstance(); + if (hasFocus){ + if (mEngine->GetButtonClick(PSP_CTRL_CIRCLE)) updateValue(); + } +} + +void OptionItem::Entering(){ + hasFocus = true; +} +bool OptionItem::Leaving(){ + hasFocus = false; + return true; +} + + +OptionItem * options[20]; +int nbitems; +OptionsList::OptionsList(){ + nbitems = 0; + current = -1; +} +OptionsList::~OptionsList(){ + for (int i = 0 ; i < nbitems; i++){ + SAFE_DELETE(options[i]); + } +} + +void OptionsList::Add(OptionItem * item){ + if (nbitems < 20){ + options[nbitems] = item; + item->x = 10; + item->y = 20 + 30*nbitems; + nbitems++; + if (current < 0){ + current = 0; + options[0]->Entering(); + } + + } +} + +void OptionsList::Render(){ + if (!nbitems){ + JLBFont * mFont = GameApp::CommonRes->GetJLBFont("graphics/f3"); + mFont->DrawString("NO OPTIONS AVAILABLE",SCREEN_WIDTH/2, 5, JGETEXT_RIGHT); + } + for (int i = 0 ; i < nbitems; i++){ + options[i]->Render(); + } +} + +void OptionsList::save(){ + for (int i = 0; i < nbitems; i++){ + options[i]->setData(); + } + GameOptions::GetInstance()->save(); +} + +void OptionsList::Update(float dt){ + JGE * mEngine = JGE::GetInstance(); + if (mEngine->GetButtonClick(PSP_CTRL_UP)) + { + if (current > 0){ + options[current]->Leaving(); + current--; + options[current]->Entering(); + } + } + else if (mEngine->GetButtonClick(PSP_CTRL_DOWN)) + { + if (current < nbitems -1){ + options[current]->Leaving(); + current++; + options[current]->Entering(); + } + } + for (int i = 0 ; i < nbitems; i++){ + options[i]->Update(dt); + } +} diff --git a/projects/mtg/src/PhaseRing.cpp b/projects/mtg/src/PhaseRing.cpp index 930677cf6..99e55b42f 100644 --- a/projects/mtg/src/PhaseRing.cpp +++ b/projects/mtg/src/PhaseRing.cpp @@ -1,85 +1,85 @@ -#include "../include/PhaseRing.h" -#include "../include/MTGDefinitions.h" -#include "../include/Player.h" -#include "../include/debug.h" - - - -/* Creates a new phase ring with the default rules */ -PhaseRing::PhaseRing(Player* players[], int nbPlayers){ - for (int i = 0; i < nbPlayers; i++){ - for (int j = 0; j ::iterator it; - for (it = ring.begin(); it != ring.end(); it++){ - Phase * currentPhase = *it; - delete(currentPhase); - } -} - -Phase * PhaseRing::getCurrentPhase(){ - if (current == ring.end()){ - current = ring.begin(); - } - return *current; -} - -Phase * PhaseRing::forward(){ - if (current != ring.end()) current++; - if (current == ring.end()) current = ring.begin(); - return *current; -} - -Phase * PhaseRing::goToPhase(int id, Player * player){ - Phase * currentPhase = *current; - while(currentPhase->id !=id || currentPhase->player !=player){ //Dangerous, risk for inifinte loop ! -#ifdef WIN32 - OutputDebugString("goto"); -#endif - currentPhase = forward(); - } - return currentPhase; -} - -int PhaseRing::addPhase(Phase * phase){ - ring.push_back(phase); - return 1; -} - -int PhaseRing::addPhaseBefore(int id, Player* player,int after_id, Player * after_player, int allOccurences){ - int result = 0; - list::iterator it; - for (it = ring.begin(); it != ring.end(); it++){ - Phase * currentPhase = *it; - if (currentPhase->id == after_id && currentPhase->player == after_player){ - result++; - ring.insert(it,NEW Phase(id,player)); - if (!allOccurences) return 1; - } - } - return result; -} -int PhaseRing::removePhase (int id, Player * player, int allOccurences){ - int result = 0; - list::iterator it = ring.begin(); - while (it != ring.end()){ - Phase * currentPhase = *it; - if (currentPhase->id == id && currentPhase->player == player){ - if (current == it) current++; //Avoid our cursor to get invalidated - it = ring.erase(it); - delete(currentPhase); - result++; - if (!allOccurences) return 1; - }else{ - it++; - } - } - return result; -} \ No newline at end of file +#include "../include/PhaseRing.h" +#include "../include/MTGDefinitions.h" +#include "../include/Player.h" +#include "../include/debug.h" + + + +/* Creates a new phase ring with the default rules */ +PhaseRing::PhaseRing(Player* players[], int nbPlayers){ + for (int i = 0; i < nbPlayers; i++){ + for (int j = 0; j ::iterator it; + for (it = ring.begin(); it != ring.end(); it++){ + Phase * currentPhase = *it; + delete(currentPhase); + } +} + +Phase * PhaseRing::getCurrentPhase(){ + if (current == ring.end()){ + current = ring.begin(); + } + return *current; +} + +Phase * PhaseRing::forward(){ + if (current != ring.end()) current++; + if (current == ring.end()) current = ring.begin(); + return *current; +} + +Phase * PhaseRing::goToPhase(int id, Player * player){ + Phase * currentPhase = *current; + while(currentPhase->id !=id || currentPhase->player !=player){ //Dangerous, risk for inifinte loop ! +#ifdef WIN32 + OutputDebugString("goto"); +#endif + currentPhase = forward(); + } + return currentPhase; +} + +int PhaseRing::addPhase(Phase * phase){ + ring.push_back(phase); + return 1; +} + +int PhaseRing::addPhaseBefore(int id, Player* player,int after_id, Player * after_player, int allOccurences){ + int result = 0; + list::iterator it; + for (it = ring.begin(); it != ring.end(); it++){ + Phase * currentPhase = *it; + if (currentPhase->id == after_id && currentPhase->player == after_player){ + result++; + ring.insert(it,NEW Phase(id,player)); + if (!allOccurences) return 1; + } + } + return result; +} +int PhaseRing::removePhase (int id, Player * player, int allOccurences){ + int result = 0; + list::iterator it = ring.begin(); + while (it != ring.end()){ + Phase * currentPhase = *it; + if (currentPhase->id == id && currentPhase->player == player){ + if (current == it) current++; //Avoid our cursor to get invalidated + it = ring.erase(it); + delete(currentPhase); + result++; + if (!allOccurences) return 1; + }else{ + it++; + } + } + return result; +} diff --git a/projects/mtg/src/PlayGuiObject.cpp b/projects/mtg/src/PlayGuiObject.cpp index 6d4fff4b9..bd60941d4 100644 --- a/projects/mtg/src/PlayGuiObject.cpp +++ b/projects/mtg/src/PlayGuiObject.cpp @@ -1,21 +1,21 @@ -#include "../include/debug.h" -#include "../include/PlayGuiObject.h" - -#include "../include/Player.h" -#include "../include/MTGGameZones.h" -#include "../include/CardDisplay.h" - +#include "../include/debug.h" +#include "../include/PlayGuiObject.h" + +#include "../include/Player.h" +#include "../include/MTGGameZones.h" +#include "../include/CardDisplay.h" + PlayGuiObject::PlayGuiObject(int id, float desiredHeight,float _x, float _y, bool hasFocus): JGuiObject(id){ defaultHeight = desiredHeight; mHeight = desiredHeight; x = _x; y = _y; mHasFocus = hasFocus; - type = 0; - wave = 0; + type = 0; + wave = 0; } - - + + void PlayGuiObject::Update(float dt){ if (mHasFocus && mHeight < defaultHeight * 1.2) { @@ -31,122 +31,122 @@ void PlayGuiObject::Update(float dt){ if (mHeight < defaultHeight) mHeight = defaultHeight; } - wave = (wave +2) % 255; + wave = (wave +2) % 255; } GuiAvatar::GuiAvatar(int id, float desiredHeight,float _x, float _y, bool hasFocus, Player * _player): PlayGuiObject(id, desiredHeight, _x, _y, hasFocus){ - player= _player; - avatarRed = 255; - currentLife = player->life; - type = GUI_AVATAR; + player= _player; + avatarRed = 255; + currentLife = player->life; + type = GUI_AVATAR; } void GuiAvatar::Render(){ - GameObserver * game = GameObserver::GetInstance(); - JRenderer * r = JRenderer::GetInstance(); - int life = player->life; - JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); - mFont->SetScale(0.75); - - //Avatar - int lifeDiff = life - currentLife; - if (lifeDiff < 0 && currentLife >0 ){ - avatarRed = 192 + (3* 255 * lifeDiff)/ currentLife / 4; - if (avatarRed<0) - avatarRed = 0; - } - currentLife= life; + GameObserver * game = GameObserver::GetInstance(); + JRenderer * r = JRenderer::GetInstance(); + int life = player->life; + JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); + mFont->SetScale(0.75); - JQuad * quad = player->mAvatar; - if(quad){ - quad->SetColor(ARGB(255,255,avatarRed,avatarRed)); - r->RenderQuad(quad,x,y); - if (mHasFocus){ - r->FillRect(x,y,quad->mWidth,quad->mHeight,ARGB(abs(wave-128), 255,255,255)); - } - } + //Avatar + int lifeDiff = life - currentLife; + if (lifeDiff < 0 && currentLife >0 ){ + avatarRed = 192 + (3* 255 * lifeDiff)/ currentLife / 4; + if (avatarRed<0) + avatarRed = 0; + } + currentLife= life; - if (avatarRed < 255){ - avatarRed+=3; - if (avatarRed >255) - avatarRed = 255; - } - if(game->currentPlayer == player){ - r->DrawRect(x-1,y-1 ,37,52,ARGB(255,0,255,0)); - }else if (game->currentActionPlayer == player){ - r->DrawRect(x,y,35,50,ARGB(255,0,0,255)); - } - if(game->isInterrupting == player){ - r->DrawRect(x,y ,35,50,ARGB(255,255,0,0)); - } + JQuad * quad = player->mAvatar; + if(quad){ + quad->SetColor(ARGB(255,255,avatarRed,avatarRed)); + r->RenderQuad(quad,x,y); + if (mHasFocus){ + r->FillRect(x,y,quad->mWidth,quad->mHeight,ARGB(abs(wave-128), 255,255,255)); + } + } - //Life - char buffer[5]; - sprintf(buffer, "%i",life); - mFont->SetColor(ARGB(128,0,0,0)); - mFont->DrawString(buffer, x+3,y+40); - mFont->SetColor(ARGB(255,255,255,255)); - mFont->DrawString(buffer, x+1,y+38); + if (avatarRed < 255){ + avatarRed+=3; + if (avatarRed >255) + avatarRed = 255; + } + if(game->currentPlayer == player){ + r->DrawRect(x-1,y-1 ,37,52,ARGB(255,0,255,0)); + }else if (game->currentActionPlayer == player){ + r->DrawRect(x,y,35,50,ARGB(255,0,0,255)); + } + if(game->isInterrupting == player){ + r->DrawRect(x,y ,35,50,ARGB(255,255,0,0)); + } + + //Life + char buffer[5]; + sprintf(buffer, "%i",life); + mFont->SetColor(ARGB(128,0,0,0)); + mFont->DrawString(buffer, x+3,y+40); + mFont->SetColor(ARGB(255,255,255,255)); + mFont->DrawString(buffer, x+1,y+38); } void GuiGameZone::toggleDisplay(){ - if (showCards){ - showCards = 0; - }else{ - showCards = 1; - cd->init(zone); - } + if (showCards){ + showCards = 0; + }else{ + showCards = 1; + cd->init(zone); + } +} + + +void GuiGameZone::Render(){ + //Texture + JQuad * quad = GameApp::CommonRes->GetQuad("back_thumb"); + float scale = defaultHeight / quad->mHeight; + quad->SetColor(ARGB(255,255,255,255)); + + JRenderer::GetInstance()->RenderQuad(quad,x,y,0.0,scale, scale); + if (mHasFocus){ + JRenderer::GetInstance()->FillRect(x,y,quad->mWidth*scale,quad->mHeight*scale,ARGB(abs(wave-128), 255,255,255)); + } + //Number of cards + JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); + char buffer[512]; + sprintf(buffer,"%i", zone->nb_cards); + mFont->SetScale(0.75); + mFont->SetColor(ARGB(128,0,0,0)); + mFont->DrawString(buffer, x+2, y+2); + mFont->SetColor(ARGB(255,255,255,255)); + mFont->DrawString(buffer, x, y); + + if (showCards) cd->Render(); +} + +void GuiGameZone::ButtonPressed(int controllerId, int controlId){ + toggleDisplay(); +} + +void GuiGameZone::Update(float dt){ + if (showCards) cd->Update(dt); + PlayGuiObject::Update(dt); +} + +GuiGameZone::GuiGameZone(int id, float desiredHeight,float _x, float _y, bool hasFocus,MTGGameZone * _zone): PlayGuiObject(id, desiredHeight, _x, _y, hasFocus), zone(_zone){ + cd = NEW CardDisplay(id, GameObserver::GetInstance(), _x, _y, this); + showCards = 0; +} + +GuiGameZone::~GuiGameZone(){ + if(cd) delete cd; +} + +GuiGraveyard::GuiGraveyard(int id, float desiredHeight,float _x, float _y, bool hasFocus,Player * player):GuiGameZone(id, desiredHeight, _x, _y, hasFocus,player->game->graveyard){ + type= GUI_GRAVEYARD; +} + + +GuiLibrary::GuiLibrary(int id, float desiredHeight,float _x, float _y, bool hasFocus,Player * player):GuiGameZone(id, desiredHeight, _x, _y, hasFocus,player->game->library){ + type = GUI_LIBRARY; } - - void GuiGameZone::Render(){ - //Texture - JQuad * quad = GameApp::CommonRes->GetQuad("back_thumb"); - float scale = defaultHeight / quad->mHeight; - quad->SetColor(ARGB(255,255,255,255)); - - JRenderer::GetInstance()->RenderQuad(quad,x,y,0.0,scale, scale); - if (mHasFocus){ - JRenderer::GetInstance()->FillRect(x,y,quad->mWidth*scale,quad->mHeight*scale,ARGB(abs(wave-128), 255,255,255)); - } - //Number of cards - JLBFont * mFont = GameApp::CommonRes->GetJLBFont(MAIN_FONT); - char buffer[512]; - sprintf(buffer,"%i", zone->nb_cards); - mFont->SetScale(0.75); - mFont->SetColor(ARGB(128,0,0,0)); - mFont->DrawString(buffer, x+2, y+2); - mFont->SetColor(ARGB(255,255,255,255)); - mFont->DrawString(buffer, x, y); - - if (showCards) cd->Render(); - } - - void GuiGameZone::ButtonPressed(int controllerId, int controlId){ - toggleDisplay(); - } - - void GuiGameZone::Update(float dt){ - if (showCards) cd->Update(dt); - PlayGuiObject::Update(dt); - } - - GuiGameZone::GuiGameZone(int id, float desiredHeight,float _x, float _y, bool hasFocus,MTGGameZone * _zone): PlayGuiObject(id, desiredHeight, _x, _y, hasFocus), zone(_zone){ - cd = NEW CardDisplay(id, GameObserver::GetInstance(), _x, _y, this); - showCards = 0; - } - - GuiGameZone::~GuiGameZone(){ - if(cd) delete cd; - } - - GuiGraveyard::GuiGraveyard(int id, float desiredHeight,float _x, float _y, bool hasFocus,Player * player):GuiGameZone(id, desiredHeight, _x, _y, hasFocus,player->game->graveyard){ - type= GUI_GRAVEYARD; - } - - - GuiLibrary::GuiLibrary(int id, float desiredHeight,float _x, float _y, bool hasFocus,Player * player):GuiGameZone(id, desiredHeight, _x, _y, hasFocus,player->game->library){ - type = GUI_LIBRARY; - } - diff --git a/projects/mtg/src/PlayGuiObjectController.cpp b/projects/mtg/src/PlayGuiObjectController.cpp index e125d4c47..b3e590e9c 100644 --- a/projects/mtg/src/PlayGuiObjectController.cpp +++ b/projects/mtg/src/PlayGuiObjectController.cpp @@ -1,11 +1,11 @@ -#include "../include/debug.h" -#include "../include/PlayGuiObjectController.h" - +#include "../include/debug.h" +#include "../include/PlayGuiObjectController.h" + #include "../include/PlayGuiObject.h" -#include "../include/GameObserver.h" - -bool PlayGuiObjectController::showBigCards = true; - +#include "../include/GameObserver.h" + +bool PlayGuiObjectController::showBigCards = true; + int PlayGuiObjectController::getClosestItem(int direction){ return getClosestItem(direction, 35); } @@ -19,153 +19,153 @@ int PlayGuiObjectController::getClosestItem(int direction, float tolerance){ return mCurr; } - float maxDist = SCREEN_WIDTH * SCREEN_WIDTH; + float maxDist = SCREEN_WIDTH * SCREEN_WIDTH; PlayGuiObject * current = (PlayGuiObject *)mObjects[mCurr]; - int closest_match = -1; - int available = 0; - float x0, y0, x1, y1; - x0 = current->x; - y0 = current->y; + int closest_match = -1; + int available = 0; + float x0, y0, x1, y1; + x0 = current->x; + y0 = current->y; for (int i=0;ix; - y1 = other->y; - float dist = (x0-x1)*(x0-x1) + (y0-y1)*(y0-y1); - if (dist>=maxDist) continue; - //Potential match ! - int ok = 0; - switch(direction){ - case DIR_DOWN: - if (y1 > y0){ - available = 1; - if (fabs(x0-x1) < tolerance ) ok = 1; - } - break; - case DIR_UP: - if (y1 < y0){ - available = 1; - if (fabs(x0-x1) < tolerance ) ok = 1; - } - break; - case DIR_LEFT: - if (x1 < x0){ - available = 1; - if (fabs(y0-y1) < tolerance ) ok = 1; - } - break; - case DIR_RIGHT: - if (x1 > x0){ - available = 1; - if (fabs(y0-y1) < tolerance ) ok = 1; - } - break; - } - if (ok){ - closest_match = i; - maxDist = dist; - } - } - if (closest_match == -1){ - if (available) return getClosestItem(direction,tolerance+5); - return mCurr; - } - return closest_match; + if (i == mCurr) continue; + PlayGuiObject * other = (PlayGuiObject *) mObjects[i]; + x1 = other->x; + y1 = other->y; + float dist = (x0-x1)*(x0-x1) + (y0-y1)*(y0-y1); + if (dist>=maxDist) continue; + //Potential match ! + int ok = 0; + switch(direction){ + case DIR_DOWN: + if (y1 > y0){ + available = 1; + if (fabs(x0-x1) < tolerance ) ok = 1; + } + break; + case DIR_UP: + if (y1 < y0){ + available = 1; + if (fabs(x0-x1) < tolerance ) ok = 1; + } + break; + case DIR_LEFT: + if (x1 < x0){ + available = 1; + if (fabs(y0-y1) < tolerance ) ok = 1; + } + break; + case DIR_RIGHT: + if (x1 > x0){ + available = 1; + if (fabs(y0-y1) < tolerance ) ok = 1; + } + break; + } + if (ok){ + closest_match = i; + maxDist = dist; + } + } + if (closest_match == -1){ + if (available) return getClosestItem(direction,tolerance+5); + return mCurr; + } + return closest_match; } /* -int PlayGuiObjectController::getClosestItem(int direction, float tolerance){ + int PlayGuiObjectController::getClosestItem(int direction, float tolerance){ if (mCount == 0){ - return -1; + return -1; } if (mCount == 1){ - return mCurr; + return mCurr; } - float MaxTolerance = SCREEN_HEIGHT; + float MaxTolerance = SCREEN_HEIGHT; PlayGuiObject * current = (PlayGuiObject *)mObjects[mCurr]; int found = 0; int closest_match_id = -1; for (int i=0;ix; - y0 = current->y; - x1 = other->x; - y1 = other->y; - closest = closest_match->y - y0; - break; - case DIR_UP: - x0 = current->x; - y0 = other->y; - x1 = other->x; - y1 = current->y; - closest = y1 - closest_match->y; - break; - case DIR_LEFT: - MaxTolerance = SCREEN_WIDTH; - x0 = current->y; - y1 = current->x; - x1 = other->y; - y0 = other->x; - closest = y1 - closest_match->x; - break; - case DIR_RIGHT: - MaxTolerance = SCREEN_WIDTH; - x0 = current->y; - fprintf(stderr, "distance STEP 401\n"); - - y0 = current->x; - fprintf(stderr, "distance STEP 402\n"); - x1 = other->y; - fprintf(stderr, "distance STEP 403\n"); - y1 = other->x; - fprintf(stderr, "distance STEP 404\n"); - closest = closest_match->x - y0; - fprintf(stderr, "distance STEP 405\n"); - break; - } - fprintf(stderr, "distance STEP 5\n"); - float distance = y1-y0; - float lateral_distance = fabs(x1-x0); - fprintf(stderr, "distance STEP 6 \n"); - if (lateral_distance < tolerance){ - fprintf(stderr, "distance STEP 7\n"); - if (distance > 0 && (!found || (distance < closest && closest > 0 ))){ + fprintf(stderr, "distance STEP 3-%i\n", i); + if (i != mCurr){ //Don't wanna return the same object as currently selected + if (closest_match_id == -1){ + closest_match_id = i; + } + if (mObjects[i]!=NULL){ + float x0, y0, x1, y1,closest; + PlayGuiObject * closest_match = (PlayGuiObject *)mObjects[closest_match_id]; + PlayGuiObject * other = (PlayGuiObject *) mObjects[i]; + fprintf(stderr, "distance STEP 4-%i\n", i); + switch(direction){ + case DIR_DOWN: + x0 = current->x; + y0 = current->y; + x1 = other->x; + y1 = other->y; + closest = closest_match->y - y0; + break; + case DIR_UP: + x0 = current->x; + y0 = other->y; + x1 = other->x; + y1 = current->y; + closest = y1 - closest_match->y; + break; + case DIR_LEFT: + MaxTolerance = SCREEN_WIDTH; + x0 = current->y; + y1 = current->x; + x1 = other->y; + y0 = other->x; + closest = y1 - closest_match->x; + break; + case DIR_RIGHT: + MaxTolerance = SCREEN_WIDTH; + x0 = current->y; + fprintf(stderr, "distance STEP 401\n"); - found = 1; - closest_match_id = i; - fprintf(stderr, "distance STEP 8\n"); - } - } - }// if (mObjects[i]!=NULL) - } + y0 = current->x; + fprintf(stderr, "distance STEP 402\n"); + x1 = other->y; + fprintf(stderr, "distance STEP 403\n"); + y1 = other->x; + fprintf(stderr, "distance STEP 404\n"); + closest = closest_match->x - y0; + fprintf(stderr, "distance STEP 405\n"); + break; + } + fprintf(stderr, "distance STEP 5\n"); + float distance = y1-y0; + float lateral_distance = fabs(x1-x0); + fprintf(stderr, "distance STEP 6 \n"); + if (lateral_distance < tolerance){ + fprintf(stderr, "distance STEP 7\n"); + if (distance > 0 && (!found || (distance < closest && closest > 0 ))){ + + found = 1; + closest_match_id = i; + fprintf(stderr, "distance STEP 8\n"); + } + } + }// if (mObjects[i]!=NULL) + } } if (!found){ fprintf(stderr, "NOT FOUND !\n"); - if (tolerance < MaxTolerance){ - fprintf(stderr, "distance STEP 9\n"); - return getClosestItem(direction, tolerance + 5); - }else{ - fprintf(stderr, "Closest Match ID: %i\n", mCurr); - return mCurr; - } + if (tolerance < MaxTolerance){ + fprintf(stderr, "distance STEP 9\n"); + return getClosestItem(direction, tolerance + 5); + }else{ + fprintf(stderr, "Closest Match ID: %i\n", mCurr); + return mCurr; + } } fprintf(stderr, "Closest Match ID: %i\n", closest_match_id); return closest_match_id; -} + } */ void PlayGuiObjectController::Update(float dt){ for (int i=0;iGetButtonClick(mActionButton)){ - if (mObjects[mCurr] != NULL && mObjects[mCurr]->ButtonPressed()){ - game->ButtonPressed(mId, (PlayGuiObject *)mObjects[mCurr]); - return; - } - } - if (mEngine->GetButtonClick(PSP_CTRL_CROSS)){ - game->cancelCurrentAction(); - } - } + if (!mCount) + return; + if (game != NULL){ + if (mEngine->GetButtonClick(mActionButton)){ + if (mObjects[mCurr] != NULL && mObjects[mCurr]->ButtonPressed()){ + game->ButtonPressed(mId, (PlayGuiObject *)mObjects[mCurr]); + return; + } + } + if (mEngine->GetButtonClick(PSP_CTRL_CROSS)){ + game->cancelCurrentAction(); + } + } - if (mEngine->GetButtonState(PSP_CTRL_LEFT)) + if (mEngine->GetButtonState(PSP_CTRL_LEFT)) + { + if (KeyRepeated(PSP_CTRL_LEFT, dt)) { - if (KeyRepeated(PSP_CTRL_LEFT, dt)) - { - int n = getClosestItem(DIR_LEFT); - if (n != mCurr && mObjects[mCurr] != NULL && mObjects[mCurr]->Leaving(PSP_CTRL_LEFT)) - { - mCurr = n; - mObjects[mCurr]->Entering(); - } - } + int n = getClosestItem(DIR_LEFT); + if (n != mCurr && mObjects[mCurr] != NULL && mObjects[mCurr]->Leaving(PSP_CTRL_LEFT)) + { + mCurr = n; + mObjects[mCurr]->Entering(); + } } - else if (mEngine->GetButtonState(PSP_CTRL_RIGHT)) + } + else if (mEngine->GetButtonState(PSP_CTRL_RIGHT)) + { + if (KeyRepeated(PSP_CTRL_RIGHT, dt)) { - if (KeyRepeated(PSP_CTRL_RIGHT, dt)) - { - int n = getClosestItem(DIR_RIGHT); - if (n != mCurr && mObjects[mCurr] != NULL && mObjects[mCurr]->Leaving(PSP_CTRL_RIGHT)) - { - mCurr = n; - mObjects[mCurr]->Entering(); - } - } + int n = getClosestItem(DIR_RIGHT); + if (n != mCurr && mObjects[mCurr] != NULL && mObjects[mCurr]->Leaving(PSP_CTRL_RIGHT)) + { + mCurr = n; + mObjects[mCurr]->Entering(); + } } - else if (mEngine->GetButtonState(PSP_CTRL_UP)) + } + else if (mEngine->GetButtonState(PSP_CTRL_UP)) + { + if (KeyRepeated(PSP_CTRL_UP, dt)) { - if (KeyRepeated(PSP_CTRL_UP, dt)) - { - int n = getClosestItem(DIR_UP); - if (n != mCurr && mObjects[mCurr] != NULL && mObjects[mCurr]->Leaving(PSP_CTRL_UP)) - { - mCurr = n; - mObjects[mCurr]->Entering(); - } - } + int n = getClosestItem(DIR_UP); + if (n != mCurr && mObjects[mCurr] != NULL && mObjects[mCurr]->Leaving(PSP_CTRL_UP)) + { + mCurr = n; + mObjects[mCurr]->Entering(); + } } - else if (mEngine->GetButtonState(PSP_CTRL_DOWN)) + } + else if (mEngine->GetButtonState(PSP_CTRL_DOWN)) + { + if (KeyRepeated(PSP_CTRL_DOWN, dt)) { - if (KeyRepeated(PSP_CTRL_DOWN, dt)) - { - int n = getClosestItem(DIR_DOWN); - if (n != mCurr && mObjects[mCurr] != NULL && mObjects[mCurr]->Leaving(PSP_CTRL_DOWN)) - { - mCurr = n; - mObjects[mCurr]->Entering(); - } - } - }else if (mEngine->GetButtonClick(PSP_CTRL_TRIANGLE)){ - showBigCards = !showBigCards; + int n = getClosestItem(DIR_DOWN); + if (n != mCurr && mObjects[mCurr] != NULL && mObjects[mCurr]->Leaving(PSP_CTRL_DOWN)) + { + mCurr = n; + mObjects[mCurr]->Entering(); + } } + }else if (mEngine->GetButtonClick(PSP_CTRL_TRIANGLE)){ + showBigCards = !showBigCards; + } - else{ - mLastKey = 0; - } + else{ + mLastKey = 0; + } diff --git a/projects/mtg/src/Player.cpp b/projects/mtg/src/Player.cpp index 56a483afe..b310a70ee 100644 --- a/projects/mtg/src/Player.cpp +++ b/projects/mtg/src/Player.cpp @@ -1,85 +1,85 @@ -#include "../include/debug.h" -#include "../include/Player.h" -#include "../include/GameObserver.h" - - - -Player::Player(MTGPlayerCards * _deck, string file): Damageable(20){ - deckFile = file; - game = _deck; - game->setOwner(this); - manaPool = NEW ManaCost(); - canPutLandsIntoPlay = 1; - mAvatar = NULL; - type_as_damageable = DAMAGEABLE_PLAYER; -} - -Player::~Player(){ - if (manaPool) delete manaPool; - if (mAvatarTex) delete mAvatarTex; - if (mAvatar) delete mAvatar; -} - -MTGInPlay * Player::inPlay(){ - return game->inPlay; -} - -int Player::getId(){ - GameObserver * game = GameObserver::GetInstance(); - for (int i= 0; i < 2; i++){ - if (game->players[i] == this) return i; - } - return -1; -} - -JQuad * Player::getIcon(){ - return mAvatar; -} - -Player * Player::opponent(){ - GameObserver * game = GameObserver::GetInstance(); - for (int i= 0; i < 2; i++){ - if (game->players[i] != this) return game->players[i]; - } - return NULL; -} - -HumanPlayer::HumanPlayer(MTGPlayerCards * _deck, char * file):Player(_deck, file){ - mAvatarTex = JRenderer::GetInstance()->LoadTexture("player/avatar.jpg", TEX_TYPE_USE_VRAM); - if (mAvatarTex) - mAvatar = NEW JQuad(mAvatarTex, 0, 0, 35, 50); -} - -ManaCost * Player::getManaPool(){ - return manaPool; -} - -int Player::manaBurn(){ - int burn = manaPool->getConvertedCost(); - life -= burn; - manaPool->init(); - return burn; -} - - -int Player::testLife(){ - if (life <=0){ - #if defined (WIN32) || defined (LINUX) -//char buf[4096], *p = buf; -//sprintf(buf, "--Diff color TEST %i : %i\n", i, cost[i]); -OutputDebugString("GAME OVER\n"); -#endif - //return GameObserver::GetInstance()->endOfGame(); - } - return life; -} - -int Player::afterDamage(){ - return testLife(); -} - -//Cleanup phase at the end of a turn -void Player::cleanupPhase(){ - game->inPlay->cleanupPhase(); - game->graveyard->cleanupPhase(); -} +#include "../include/debug.h" +#include "../include/Player.h" +#include "../include/GameObserver.h" + + + +Player::Player(MTGPlayerCards * _deck, string file): Damageable(20){ + deckFile = file; + game = _deck; + game->setOwner(this); + manaPool = NEW ManaCost(); + canPutLandsIntoPlay = 1; + mAvatar = NULL; + type_as_damageable = DAMAGEABLE_PLAYER; +} + +Player::~Player(){ + if (manaPool) delete manaPool; + if (mAvatarTex) delete mAvatarTex; + if (mAvatar) delete mAvatar; +} + +MTGInPlay * Player::inPlay(){ + return game->inPlay; +} + +int Player::getId(){ + GameObserver * game = GameObserver::GetInstance(); + for (int i= 0; i < 2; i++){ + if (game->players[i] == this) return i; + } + return -1; +} + +JQuad * Player::getIcon(){ + return mAvatar; +} + +Player * Player::opponent(){ + GameObserver * game = GameObserver::GetInstance(); + for (int i= 0; i < 2; i++){ + if (game->players[i] != this) return game->players[i]; + } + return NULL; +} + +HumanPlayer::HumanPlayer(MTGPlayerCards * _deck, char * file):Player(_deck, file){ + mAvatarTex = JRenderer::GetInstance()->LoadTexture("player/avatar.jpg", TEX_TYPE_USE_VRAM); + if (mAvatarTex) + mAvatar = NEW JQuad(mAvatarTex, 0, 0, 35, 50); +} + +ManaCost * Player::getManaPool(){ + return manaPool; +} + +int Player::manaBurn(){ + int burn = manaPool->getConvertedCost(); + life -= burn; + manaPool->init(); + return burn; +} + + +int Player::testLife(){ + if (life <=0){ +#if defined (WIN32) || defined (LINUX) + //char buf[4096], *p = buf; + //sprintf(buf, "--Diff color TEST %i : %i\n", i, cost[i]); + OutputDebugString("GAME OVER\n"); +#endif + //return GameObserver::GetInstance()->endOfGame(); + } + return life; +} + +int Player::afterDamage(){ + return testLife(); +} + +//Cleanup phase at the end of a turn +void Player::cleanupPhase(){ + game->inPlay->cleanupPhase(); + game->graveyard->cleanupPhase(); +} diff --git a/projects/mtg/src/PlayerData.cpp b/projects/mtg/src/PlayerData.cpp index e712b4849..477ec4d7a 100644 --- a/projects/mtg/src/PlayerData.cpp +++ b/projects/mtg/src/PlayerData.cpp @@ -1,40 +1,40 @@ -#include "../include/debug.h" -#include "../include/PlayerData.h" - -#include -#include - -PlayerData::PlayerData(MTGAllCards * allcards){ - //CREDITS - credits = 3000; //Default value - std::ifstream file(PLAYER_SAVEFILE); - std::string s; - if(file){ - if(std::getline(file,s)){ - credits = atoi(s.c_str()); - }else{ - //TODO error management - } - file.close(); - } - - //COLLECTION - collection = NEW MTGDeck("Res/player/collection.dat", allcards->mCache , allcards); -} - - -int PlayerData::save(){ - std::ofstream file(PLAYER_SAVEFILE); - char writer[10]; - if (file){ - sprintf(writer,"%i\n", credits); - file<save(); - return 1; +#include "../include/debug.h" +#include "../include/PlayerData.h" + +#include +#include + +PlayerData::PlayerData(MTGAllCards * allcards){ + //CREDITS + credits = 3000; //Default value + std::ifstream file(PLAYER_SAVEFILE); + std::string s; + if(file){ + if(std::getline(file,s)){ + credits = atoi(s.c_str()); + }else{ + //TODO error management + } + file.close(); + } + + //COLLECTION + collection = NEW MTGDeck("Res/player/collection.dat", allcards->mCache , allcards); +} + + +int PlayerData::save(){ + std::ofstream file(PLAYER_SAVEFILE); + char writer[10]; + if (file){ + sprintf(writer,"%i\n", credits); + file<save(); + return 1; } PlayerData::~PlayerData(){ - SAFE_DELETE(collection); -} \ No newline at end of file + SAFE_DELETE(collection); +} diff --git a/projects/mtg/src/PriceList.cpp b/projects/mtg/src/PriceList.cpp index 6981f4516..6fd08b1c8 100644 --- a/projects/mtg/src/PriceList.cpp +++ b/projects/mtg/src/PriceList.cpp @@ -1,88 +1,88 @@ -#include "../include/debug.h" -#include "../include/PriceList.h" - - -Price::Price(int _cardid, int _price): cardid(_cardid),price(_price){ -} - - - -PriceList::PriceList(const char * _filename, MTGAllCards * _collection):collection(_collection){ - nbprices = 0; - filename = _filename; - std::ifstream file(_filename); - std::string cardid; - std::string price; - if(file){ - while(std::getline(file,cardid)){ - std::getline(file,price); - prices[nbprices]= NEW Price(atoi(cardid.c_str()), atoi(price.c_str())); - nbprices++; - } - file.close(); - } -} - - -PriceList::~PriceList(){ - for (int i = 0; i < nbprices; i++){ - delete (prices[i]); - } - nbprices = 0; -} - -int PriceList::save(){ - std::ofstream file(filename.c_str()); - char writer[20]; - if (file){ - for (int i = 0; icardid, prices[i]->price); - file<cardid == cardId){ - return prices[i]->price; - } - } - char rarity = collection->getCardById(cardId)->getRarity(); - switch(rarity){ - case RARITY_M: - return 3000; - break; - case RARITY_R: - return 500; - break; - case RARITY_U: - return 100; - break; - case RARITY_C: - return 20; - break; - case RARITY_L: - return 5; - break; - default: - return 20; - break; - - } - -} - -int PriceList::setPrice(int cardId, int price){ - for(int i = 0; i < nbprices; i++){ - if (prices[i]->cardid == cardId){ - prices[i]->price = price; - return prices[i]->price; - } - } - prices[nbprices] = NEW Price(cardId, price); - nbprices++; - return prices[nbprices-1]->price; -} +#include "../include/debug.h" +#include "../include/PriceList.h" + + +Price::Price(int _cardid, int _price): cardid(_cardid),price(_price){ +} + + + +PriceList::PriceList(const char * _filename, MTGAllCards * _collection):collection(_collection){ + nbprices = 0; + filename = _filename; + std::ifstream file(_filename); + std::string cardid; + std::string price; + if(file){ + while(std::getline(file,cardid)){ + std::getline(file,price); + prices[nbprices]= NEW Price(atoi(cardid.c_str()), atoi(price.c_str())); + nbprices++; + } + file.close(); + } +} + + +PriceList::~PriceList(){ + for (int i = 0; i < nbprices; i++){ + delete (prices[i]); + } + nbprices = 0; +} + +int PriceList::save(){ + std::ofstream file(filename.c_str()); + char writer[20]; + if (file){ + for (int i = 0; icardid, prices[i]->price); + file<cardid == cardId){ + return prices[i]->price; + } + } + char rarity = collection->getCardById(cardId)->getRarity(); + switch(rarity){ + case RARITY_M: + return 3000; + break; + case RARITY_R: + return 500; + break; + case RARITY_U: + return 100; + break; + case RARITY_C: + return 20; + break; + case RARITY_L: + return 5; + break; + default: + return 20; + break; + + } + +} + +int PriceList::setPrice(int cardId, int price){ + for(int i = 0; i < nbprices; i++){ + if (prices[i]->cardid == cardId){ + prices[i]->price = price; + return prices[i]->price; + } + } + prices[nbprices] = NEW Price(cardId, price); + nbprices++; + return prices[nbprices-1]->price; +} diff --git a/projects/mtg/src/ShopItem.cpp b/projects/mtg/src/ShopItem.cpp index b8a1fc1b0..c9cb04ed2 100644 --- a/projects/mtg/src/ShopItem.cpp +++ b/projects/mtg/src/ShopItem.cpp @@ -1,288 +1,288 @@ -#include "../include/debug.h" -#include "../include/ShopItem.h" -#include "../include/CardGui.h" - - -ShopItem::ShopItem(int id, JLBFont *font, char* text, JQuad * _quad,JQuad * _thumb, int x, int y, bool hasFocus, int _price): JGuiObject(id), mFont(font), mText(text), mX(x), mY(y), quad(_quad), thumb(_thumb), price(_price) -{ - quantity = 10; - card = NULL; - mHasFocus = hasFocus; - - mScale = 1.0f; - mTargetScale = 1.0f; - - - - if (hasFocus) - Entering(); - mFont->SetScale(1.2f); - -} - -ShopItem::ShopItem(int id, JLBFont *font, int _cardid, int x, int y, bool hasFocus, MTGAllCards * collection, int _price): JGuiObject(id), mFont(font), mX(x), mY(y), price(_price){ - mHasFocus = hasFocus; - - mScale = 1.0f; - mTargetScale = 1.0f; - - - - if (hasFocus) - Entering(); - mFont->SetScale(1.2f); - - card = collection->getCardById(_cardid); - quantity = 1; - if (card->getRarity() == RARITY_L) quantity = 50; - quad = NULL; - thumb = NULL; -} - - -ShopItem::~ShopItem(){ - -} - -const char * ShopItem::getText(){ - return mText.c_str(); -} - - -void ShopItem::Render(){ - JRenderer * renderer = JRenderer::GetInstance(); - renderer->FillRect(mX-5, mY-5,230,35, ARGB(128,0,0,0)); - if (card){ - thumb = card->getThumb(); - mText= card->name; - } - - if (thumb){ - renderer->RenderQuad(thumb,mX,mY,0,mScale * 0.45,mScale * 0.45); - }else{ - //NOTHING - } - if (mHasFocus){ - if (card){ - quad = card->getQuad(); - } - if (quad){ - renderer->RenderQuad(quad,mX + SCREEN_WIDTH/2 + 20,5,0, 0.9f,0.9f); - }else{ - if (card) CardGui::alternateRender(card,mFont,NULL,mX + SCREEN_WIDTH/2 + 100 + 20,133,0, 0.9f); - //TODO - } - mFont->SetColor(ARGB(255,255,255,0)); - }else{ - mFont->SetColor(ARGB(255,255,255,255)); - } - if (!quantity){ - mFont->SetColor(ARGB(255,128,128,128)); - } - mFont->SetScale(mScale); - mFont->DrawString(mText.c_str(),mX + 30,mY); -} - - - - -void ShopItem::Update(float dt) -{ - if (mScale < mTargetScale) - { - mScale += 8.0f*dt; - if (mScale > mTargetScale) - mScale = mTargetScale; - } - else if (mScale > mTargetScale) - { - mScale -= 8.0f*dt; - if (mScale < mTargetScale) - mScale = mTargetScale; - } -} - - - - -void ShopItem::Entering() -{ - - mHasFocus = true; - mTargetScale = 1.2f; -} - - -bool ShopItem::Leaving(u32 key) -{ - mHasFocus = false; - mTargetScale = 1.0f; - return true; -} - - -bool ShopItem::ButtonPressed() -{ - return (quantity >0); -} - - -ShopItems::ShopItems(int id, JGuiListener* listener, JLBFont* font, int x, int y, MTGAllCards * _collection, int _setId): JGuiController(id, listener), mX(x), mY(y), mFont(font), collection(_collection), setId(_setId){ - mHeight = 0; - showPriceDialog = -1; - dialog = NULL; - pricelist = NEW PriceList("Res/settings/prices.dat",_collection); - playerdata = NEW PlayerData(_collection); - display = NULL; -} - - - -void ShopItems::Add(int cardid){ - int rnd = (rand() % 20); - int price = pricelist->getPrice(cardid); - price = price + price * (rnd -10)/100; - JGuiController::Add(NEW ShopItem(mCount, mFont, cardid, mX + 10, mY + 10 + mHeight, (mCount == 0),collection, price)); - mHeight += 40; -} - -void ShopItems::Add(char * text, JQuad * quad,JQuad * thumb, int price){ - JGuiController::Add(NEW ShopItem(mCount, mFont, text, quad, thumb, mX + 10, mY + 10 + mHeight, (mCount == 0), price)); - mHeight += 40; -} - -void ShopItems::Update(float dt){ - if (display){ - display->CheckUserInput(dt); - if (display) display->Update(dt); - }else{ - if (showPriceDialog!=-1){ - ShopItem * item = ((ShopItem *)mObjects[showPriceDialog]); - int price = item->price; - char buffer[4096]; - sprintf(buffer,"%s : %i credits",item->getText(),price); - if(!dialog){ - dialog = NEW SimpleMenu(1,this,mFont,SCREEN_WIDTH-300,SCREEN_HEIGHT/2,270,buffer); - dialog->Add(1,"Yes"); - dialog->Add(2,"No"); - } - else{ - dialog->Update(dt); - } - }else{ - SAFE_DELETE(dialog); - JGuiController::Update(dt); - } - } - -} - - -void ShopItems::Render(){ - JGuiController::Render(); - if (showPriceDialog==-1){ - - }else{ - if(dialog){ - dialog->Render(); - } - } - char credits[512]; - sprintf(credits,"credits: %i", playerdata->credits); - mFont->SetScale(1.2); - mFont->SetColor(ARGB(200,0,0,0)); - mFont->DrawString(credits,SCREEN_WIDTH-148, SCREEN_HEIGHT - 13); - mFont->SetColor(ARGB(255,255,255,255)); - mFont->DrawString(credits,SCREEN_WIDTH-150, SCREEN_HEIGHT - 15); - if (display) display->Render(); -} - -void ShopItems::pricedialog(int id, int mode){ - if (mode){ - showPriceDialog = id; - }else{ - showPriceDialog = -1; - } -} - -void ShopItems::ButtonPressed(int controllerId, int controlId){ - if (controllerId == 12){ - safeDeleteDisplay(); - return; - } - - ShopItem * item = ((ShopItem *)mObjects[showPriceDialog]); - int price = item->price; - switch(controlId){ - case 1: - if (playerdata->credits >= price){ - playerdata->credits -= price; - if (item->card){ - int rnd = (rand() % 5); - price = price + (rnd * price)/100; - pricelist->setPrice(item->card->getMTGId(),price); - playerdata->collection->add(item->card); - item->quantity--; - }else{ - safeDeleteDisplay(); - display = new CardDisplay(12,NULL, SCREEN_WIDTH - 200, SCREEN_HEIGHT/2,this,NULL,5); - int curNbcards = playerdata->collection->totalCards(); - if (showPriceDialog == 0){ - //Starter Deck - playerdata->collection->addRandomCards(3,setId,RARITY_R,NULL); - playerdata->collection->addRandomCards(9, setId,RARITY_U,NULL); - playerdata->collection->addRandomCards(48, setId,RARITY_C,NULL); - }else{ - //Booster - playerdata->collection->addRandomCards(1, setId,RARITY_R); - playerdata->collection->addRandomCards(3, setId,RARITY_U); - playerdata->collection->addRandomCards(11, setId,RARITY_C); - } - int newNbCards = playerdata->collection->totalCards();; - for (int i = curNbcards; i < newNbCards ; i++){ - MTGCardInstance * card = NEW MTGCardInstance(playerdata->collection->_(i), NULL); - displayCards[i-curNbcards] = card; - display->AddCard(card); - } - } - //Remove(showPriceDialog); - showPriceDialog = -1; - }else{ - //error not enough money - } - break; - case 2: - if (item->card){ - int rnd = (rand() % 5); - price = price - (rnd * price)/100; - pricelist->setPrice(item->card->getMTGId(),price); - } - showPriceDialog = -1; - break; - } -} - - -void ShopItems::safeDeleteDisplay(){ - if (!display) return; - for (int i = 0; i < display->mCount; i++){ - delete displayCards[i]; - } - SAFE_DELETE(display); -} - -void ShopItems::saveAll(){ - savePriceList(); - playerdata->save(); -} - -void ShopItems::savePriceList(){ - pricelist->save(); -} - -ShopItems::~ShopItems(){ - SAFE_DELETE(pricelist); - SAFE_DELETE(playerdata); - SAFE_DELETE(dialog); - safeDeleteDisplay(); -} +#include "../include/debug.h" +#include "../include/ShopItem.h" +#include "../include/CardGui.h" + + +ShopItem::ShopItem(int id, JLBFont *font, char* text, JQuad * _quad,JQuad * _thumb, int x, int y, bool hasFocus, int _price): JGuiObject(id), mFont(font), mText(text), mX(x), mY(y), quad(_quad), thumb(_thumb), price(_price) +{ + quantity = 10; + card = NULL; + mHasFocus = hasFocus; + + mScale = 1.0f; + mTargetScale = 1.0f; + + + + if (hasFocus) + Entering(); + mFont->SetScale(1.2f); + +} + +ShopItem::ShopItem(int id, JLBFont *font, int _cardid, int x, int y, bool hasFocus, MTGAllCards * collection, int _price): JGuiObject(id), mFont(font), mX(x), mY(y), price(_price){ + mHasFocus = hasFocus; + + mScale = 1.0f; + mTargetScale = 1.0f; + + + + if (hasFocus) + Entering(); + mFont->SetScale(1.2f); + + card = collection->getCardById(_cardid); + quantity = 1; + if (card->getRarity() == RARITY_L) quantity = 50; + quad = NULL; + thumb = NULL; +} + + +ShopItem::~ShopItem(){ + +} + +const char * ShopItem::getText(){ + return mText.c_str(); +} + + +void ShopItem::Render(){ + JRenderer * renderer = JRenderer::GetInstance(); + renderer->FillRect(mX-5, mY-5,230,35, ARGB(128,0,0,0)); + if (card){ + thumb = card->getThumb(); + mText= card->name; + } + + if (thumb){ + renderer->RenderQuad(thumb,mX,mY,0,mScale * 0.45,mScale * 0.45); + }else{ + //NOTHING + } + if (mHasFocus){ + if (card){ + quad = card->getQuad(); + } + if (quad){ + renderer->RenderQuad(quad,mX + SCREEN_WIDTH/2 + 20,5,0, 0.9f,0.9f); + }else{ + if (card) CardGui::alternateRender(card,mFont,NULL,mX + SCREEN_WIDTH/2 + 100 + 20,133,0, 0.9f); + //TODO + } + mFont->SetColor(ARGB(255,255,255,0)); + }else{ + mFont->SetColor(ARGB(255,255,255,255)); + } + if (!quantity){ + mFont->SetColor(ARGB(255,128,128,128)); + } + mFont->SetScale(mScale); + mFont->DrawString(mText.c_str(),mX + 30,mY); +} + + + + +void ShopItem::Update(float dt) +{ + if (mScale < mTargetScale) + { + mScale += 8.0f*dt; + if (mScale > mTargetScale) + mScale = mTargetScale; + } + else if (mScale > mTargetScale) + { + mScale -= 8.0f*dt; + if (mScale < mTargetScale) + mScale = mTargetScale; + } +} + + + + +void ShopItem::Entering() +{ + + mHasFocus = true; + mTargetScale = 1.2f; +} + + +bool ShopItem::Leaving(u32 key) +{ + mHasFocus = false; + mTargetScale = 1.0f; + return true; +} + + +bool ShopItem::ButtonPressed() +{ + return (quantity >0); +} + + +ShopItems::ShopItems(int id, JGuiListener* listener, JLBFont* font, int x, int y, MTGAllCards * _collection, int _setId): JGuiController(id, listener), mX(x), mY(y), mFont(font), collection(_collection), setId(_setId){ + mHeight = 0; + showPriceDialog = -1; + dialog = NULL; + pricelist = NEW PriceList("Res/settings/prices.dat",_collection); + playerdata = NEW PlayerData(_collection); + display = NULL; +} + + + +void ShopItems::Add(int cardid){ + int rnd = (rand() % 20); + int price = pricelist->getPrice(cardid); + price = price + price * (rnd -10)/100; + JGuiController::Add(NEW ShopItem(mCount, mFont, cardid, mX + 10, mY + 10 + mHeight, (mCount == 0),collection, price)); + mHeight += 40; +} + +void ShopItems::Add(char * text, JQuad * quad,JQuad * thumb, int price){ + JGuiController::Add(NEW ShopItem(mCount, mFont, text, quad, thumb, mX + 10, mY + 10 + mHeight, (mCount == 0), price)); + mHeight += 40; +} + +void ShopItems::Update(float dt){ + if (display){ + display->CheckUserInput(dt); + if (display) display->Update(dt); + }else{ + if (showPriceDialog!=-1){ + ShopItem * item = ((ShopItem *)mObjects[showPriceDialog]); + int price = item->price; + char buffer[4096]; + sprintf(buffer,"%s : %i credits",item->getText(),price); + if(!dialog){ + dialog = NEW SimpleMenu(1,this,mFont,SCREEN_WIDTH-300,SCREEN_HEIGHT/2,270,buffer); + dialog->Add(1,"Yes"); + dialog->Add(2,"No"); + } + else{ + dialog->Update(dt); + } + }else{ + SAFE_DELETE(dialog); + JGuiController::Update(dt); + } + } + +} + + +void ShopItems::Render(){ + JGuiController::Render(); + if (showPriceDialog==-1){ + + }else{ + if(dialog){ + dialog->Render(); + } + } + char credits[512]; + sprintf(credits,"credits: %i", playerdata->credits); + mFont->SetScale(1.2); + mFont->SetColor(ARGB(200,0,0,0)); + mFont->DrawString(credits,SCREEN_WIDTH-148, SCREEN_HEIGHT - 13); + mFont->SetColor(ARGB(255,255,255,255)); + mFont->DrawString(credits,SCREEN_WIDTH-150, SCREEN_HEIGHT - 15); + if (display) display->Render(); +} + +void ShopItems::pricedialog(int id, int mode){ + if (mode){ + showPriceDialog = id; + }else{ + showPriceDialog = -1; + } +} + +void ShopItems::ButtonPressed(int controllerId, int controlId){ + if (controllerId == 12){ + safeDeleteDisplay(); + return; + } + + ShopItem * item = ((ShopItem *)mObjects[showPriceDialog]); + int price = item->price; + switch(controlId){ + case 1: + if (playerdata->credits >= price){ + playerdata->credits -= price; + if (item->card){ + int rnd = (rand() % 5); + price = price + (rnd * price)/100; + pricelist->setPrice(item->card->getMTGId(),price); + playerdata->collection->add(item->card); + item->quantity--; + }else{ + safeDeleteDisplay(); + display = new CardDisplay(12,NULL, SCREEN_WIDTH - 200, SCREEN_HEIGHT/2,this,NULL,5); + int curNbcards = playerdata->collection->totalCards(); + if (showPriceDialog == 0){ + //Starter Deck + playerdata->collection->addRandomCards(3,setId,RARITY_R,NULL); + playerdata->collection->addRandomCards(9, setId,RARITY_U,NULL); + playerdata->collection->addRandomCards(48, setId,RARITY_C,NULL); + }else{ + //Booster + playerdata->collection->addRandomCards(1, setId,RARITY_R); + playerdata->collection->addRandomCards(3, setId,RARITY_U); + playerdata->collection->addRandomCards(11, setId,RARITY_C); + } + int newNbCards = playerdata->collection->totalCards();; + for (int i = curNbcards; i < newNbCards ; i++){ + MTGCardInstance * card = NEW MTGCardInstance(playerdata->collection->_(i), NULL); + displayCards[i-curNbcards] = card; + display->AddCard(card); + } + } + //Remove(showPriceDialog); + showPriceDialog = -1; + }else{ + //error not enough money + } + break; + case 2: + if (item->card){ + int rnd = (rand() % 5); + price = price - (rnd * price)/100; + pricelist->setPrice(item->card->getMTGId(),price); + } + showPriceDialog = -1; + break; + } +} + + +void ShopItems::safeDeleteDisplay(){ + if (!display) return; + for (int i = 0; i < display->mCount; i++){ + delete displayCards[i]; + } + SAFE_DELETE(display); +} + +void ShopItems::saveAll(){ + savePriceList(); + playerdata->save(); +} + +void ShopItems::savePriceList(){ + pricelist->save(); +} + +ShopItems::~ShopItems(){ + SAFE_DELETE(pricelist); + SAFE_DELETE(playerdata); + SAFE_DELETE(dialog); + safeDeleteDisplay(); +} diff --git a/projects/mtg/src/SimpleMenu.cpp b/projects/mtg/src/SimpleMenu.cpp index 739e6e16b..dd7012fd9 100644 --- a/projects/mtg/src/SimpleMenu.cpp +++ b/projects/mtg/src/SimpleMenu.cpp @@ -1,34 +1,34 @@ -#include "../include/debug.h" -#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){ - mHeight = 0; - mWidth = width; - mX = x; - mY = y; - mFont = font; - if (_title){ - displaytitle = 1; - title = _title; - mHeight = 20; - }else{ - displaytitle = 0; - } -} - -void SimpleMenu::Render(){ - mFont->SetColor(ARGB(255,255,255,255)); - JRenderer * renderer = JRenderer::GetInstance(); - renderer->FillRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT,ARGB(70,0,0,0)); - renderer->FillRoundRect(mX,mY,mWidth,mHeight,10,ARGB(255,17,17,17)); - 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(); -} - -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; -} +#include "../include/debug.h" +#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){ + mHeight = 0; + mWidth = width; + mX = x; + mY = y; + mFont = font; + if (_title){ + displaytitle = 1; + title = _title; + mHeight = 20; + }else{ + displaytitle = 0; + } +} + +void SimpleMenu::Render(){ + mFont->SetColor(ARGB(255,255,255,255)); + JRenderer * renderer = JRenderer::GetInstance(); + renderer->FillRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT,ARGB(70,0,0,0)); + renderer->FillRoundRect(mX,mY,mWidth,mHeight,10,ARGB(255,17,17,17)); + 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(); +} + +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; +} diff --git a/projects/mtg/src/SimpleMenuItem.cpp b/projects/mtg/src/SimpleMenuItem.cpp index 0232de491..58b4481b1 100644 --- a/projects/mtg/src/SimpleMenuItem.cpp +++ b/projects/mtg/src/SimpleMenuItem.cpp @@ -1,75 +1,75 @@ -#include "../include/debug.h" -#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) -{ - - - mHasFocus = hasFocus; - - mScale = 1.0f; - mTargetScale = 1.0f; - - - - if (hasFocus) - Entering(); - mFont->SetScale(1.2f); - -} - - -void SimpleMenuItem::Render() -{ - - mFont->SetScale(mScale); - mFont->SetColor(ARGB(255,255,255,255)); - if (mHasFocus) - { - mFont->SetColor(ARGB(255,255,255,0)); - } - mFont->DrawString(mText, mX, mY, JGETEXT_CENTER); - mFont->SetScale(1.0f); -} - -void SimpleMenuItem::Update(float dt) -{ - if (mScale < mTargetScale) - { - mScale += 8.0f*dt; - if (mScale > mTargetScale) - mScale = mTargetScale; - } - else if (mScale > mTargetScale) - { - mScale -= 8.0f*dt; - if (mScale < mTargetScale) - mScale = mTargetScale; - } -} - - - - -void SimpleMenuItem::Entering() -{ - - mHasFocus = true; - mTargetScale = 1.2f; -} - - -bool SimpleMenuItem::Leaving(u32 key) -{ - mHasFocus = false; - mTargetScale = 1.0f; - return true; -} - - -bool SimpleMenuItem::ButtonPressed() -{ - return true; -} - +#include "../include/debug.h" +#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) +{ + + + mHasFocus = hasFocus; + + mScale = 1.0f; + mTargetScale = 1.0f; + + + + if (hasFocus) + Entering(); + mFont->SetScale(1.2f); + +} + + +void SimpleMenuItem::Render() +{ + + mFont->SetScale(mScale); + mFont->SetColor(ARGB(255,255,255,255)); + if (mHasFocus) + { + mFont->SetColor(ARGB(255,255,255,0)); + } + mFont->DrawString(mText, mX, mY, JGETEXT_CENTER); + mFont->SetScale(1.0f); +} + +void SimpleMenuItem::Update(float dt) +{ + if (mScale < mTargetScale) + { + mScale += 8.0f*dt; + if (mScale > mTargetScale) + mScale = mTargetScale; + } + else if (mScale > mTargetScale) + { + mScale -= 8.0f*dt; + if (mScale < mTargetScale) + mScale = mTargetScale; + } +} + + + + +void SimpleMenuItem::Entering() +{ + + mHasFocus = true; + mTargetScale = 1.2f; +} + + +bool SimpleMenuItem::Leaving(u32 key) +{ + mHasFocus = false; + mTargetScale = 1.0f; + return true; +} + + +bool SimpleMenuItem::ButtonPressed() +{ + return true; +} + diff --git a/projects/mtg/src/Subtypes.cpp b/projects/mtg/src/Subtypes.cpp index d207c397a..dc9b5d233 100644 --- a/projects/mtg/src/Subtypes.cpp +++ b/projects/mtg/src/Subtypes.cpp @@ -1,45 +1,45 @@ -#include "../include/debug.h" -#include "../include/Subtypes.h" -#include -#include - -Subtypes * Subtypes::subtypesList = NEW Subtypes(); - - - -Subtypes::Subtypes(){ - nb_items = 100; -} - -int Subtypes::Add(string value){ - int result = find(value); - if (result) return result; -#if defined (WIN32) || defined (LINUX) - char buf[4096]; - sprintf(buf, "Adding new type: *%s*\n",value.c_str()); - OutputDebugString(buf); -#endif - std::transform( value.begin(), value.end(), value.begin(), ::tolower ); - nb_items++; - values[value] = nb_items; - return nb_items; -} - -int Subtypes::Add(const char * subtype){ - string value = subtype; - return Add(value); - -} - -int Subtypes::find(string value){ - std::transform( value.begin(), value.end(), value.begin(), ::tolower ); - map::iterator it = values.find(value); - if (it != values.end()) return it->second; - return 0; -} - -int Subtypes::find(const char * subtype){ - string value = subtype; - return (find(value)); - -} \ No newline at end of file +#include "../include/debug.h" +#include "../include/Subtypes.h" +#include +#include + +Subtypes * Subtypes::subtypesList = NEW Subtypes(); + + + +Subtypes::Subtypes(){ + nb_items = 100; +} + +int Subtypes::Add(string value){ + int result = find(value); + if (result) return result; +#if defined (WIN32) || defined (LINUX) + char buf[4096]; + sprintf(buf, "Adding new type: *%s*\n",value.c_str()); + OutputDebugString(buf); +#endif + std::transform( value.begin(), value.end(), value.begin(), ::tolower ); + nb_items++; + values[value] = nb_items; + return nb_items; +} + +int Subtypes::Add(const char * subtype){ + string value = subtype; + return Add(value); + +} + +int Subtypes::find(string value){ + std::transform( value.begin(), value.end(), value.begin(), ::tolower ); + map::iterator it = values.find(value); + if (it != values.end()) return it->second; + return 0; +} + +int Subtypes::find(const char * subtype){ + string value = subtype; + return (find(value)); + +} diff --git a/projects/mtg/src/TargetChooser.cpp b/projects/mtg/src/TargetChooser.cpp index 93bb31968..5f4cd7ede 100644 --- a/projects/mtg/src/TargetChooser.cpp +++ b/projects/mtg/src/TargetChooser.cpp @@ -1,607 +1,607 @@ -#include "../include/debug.h" -#include "../include/TargetChooser.h" -#include "../include/CardDescriptor.h" -#include "../include/MTGGameZones.h" -#include "../include/GameObserver.h" -#include "../include/Subtypes.h" - - - -TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInstance * card){ - GameObserver * game = GameObserver::GetInstance(); - MTGGameZone * zones[10]; - int nbzones = 0; - int size = s.size(); - if (size != 0){ - unsigned int found; - found = s.find("player"); - if (found != string::npos){ - int maxtargets = 1; - unsigned int several = s.find_first_of('s',5); - if (several != string::npos) maxtargets = -1; - found = s.find("creature"); - if (found != string::npos){ - return NEW DamageableTargetChooser(card,maxtargets); //Any Damageable target (player, creature) - }else{ - return NEW PlayerTargetChooser(card,maxtargets); //Any player - } - }else{ - string s1; - found = s.find("|"); - if (found != string::npos){ - string s2; - s1 = s.substr(0,found); - s2 = s.substr(found+1); - while(s2.size()){ - found = s2.find(","); - string zoneName; - if (found != string::npos){ - zoneName = s2.substr(0,found); - s2 = s2.substr(found+1); - }else{ - zoneName = s2; - s2 = ""; - } - //Graveyards - if (zoneName.compare("mygraveyard") == 0){ - zones[nbzones] = game->currentlyActing()->game->graveyard; - }else if(zoneName.compare("opponentgraveyard") == 0){ - zones[nbzones] = game->currentlyActing()->opponent()->game->graveyard; - }else if(zoneName.compare("graveyard") == 0){ - zones[nbzones] = game->players[0]->game->graveyard; - nbzones++; - zones[nbzones] = game->players[1]->game->graveyard; - }else{ - - //inPlay - if (zoneName.compare("myinplay") == 0){ - zones[nbzones] = game->currentlyActing()->game->inPlay; - }else if(zoneName.compare("opponentinplay") == 0){ - zones[nbzones] = game->currentlyActing()->opponent()->game->inPlay; - }else if(zoneName.compare("inplay") == 0){ - zones[nbzones] = game->players[0]->game->inPlay; - nbzones++; - zones[nbzones] = game->players[1]->game->inPlay; - }else{ - zones[nbzones] = game->currentlyActing()->game->inPlay; - } - } - nbzones++; - } - }else{ - s1 = s; - nbzones = 2; - zones[0]= game->players[0]->game->inPlay; - zones[1]= game->players[1]->game->inPlay; - } - - TargetChooser * tc = NULL; - int maxtargets = 1; - CardDescriptor * cd = NULL; - - while(s1.size()){ - found = s1.find(","); - string typeName; - if (found != string::npos){ - typeName = s1.substr(0,found); - s1 = s1.substr(found+1); - }else{ - typeName = s1; - s1 = ""; - } - - //Advanced cards caracteristics ? - found = typeName.find("["); - if (found != string::npos){ - int nbminuses = 0; - int end = typeName.find("]"); -#ifdef WIN32 - OutputDebugString("Advanced Attributes 1 \n"); -#endif - string attributes = typeName.substr(found+1,end-found-1); -#ifdef WIN32 - OutputDebugString(attributes.c_str()); - OutputDebugString("\n"); -#endif - cd = NEW CardDescriptor(); - while(attributes.size()){ - unsigned int found2 = attributes.find(";"); - string attribute; - if (found2 != string::npos){ - attribute = attributes.substr(0,found2); - attributes = attributes.substr(found2+1); - }else{ - attribute = attributes; - attributes = ""; - } - int minus = 0; - if (attribute[0] == '-'){ -#ifdef WIN32 - OutputDebugString("MINUS\n"); -#endif - minus = 1; - nbminuses++; - } -#ifdef WIN32 - OutputDebugString(attribute.c_str()); - OutputDebugString("\n"); -#endif - //Attacker - if (attribute.find("attacking") != string::npos){ - if (minus){ - cd->attacker = -1; - }else{ - cd->attacker = 1; - } - - //Blocker - }else if (attribute.find("blocking") != string::npos){ - if (minus){ - cd->defenser = (MTGCardInstance *)-1; //Oh yeah, that's ugly.... - }else{ - cd->defenser = (MTGCardInstance *)1; - } - - //Tapped, untapped - }else if (attribute.find("tapped") != string::npos){ - if (minus){ - cd->tapped = -1; - }else{ - cd->tapped = 1; - } - }else{ - int attributefound = 0; - //Colors - for (int cid = 0; cid < MTG_NB_COLORS; cid++){ - if (attribute.find(MTGColorStrings[cid]) != string::npos){ - attributefound = 1; - if (minus){ - cd->colors[cid] = -1; - }else{ - cd->colors[cid] = 1; - } - } - } - if (!attributefound){ - //Abilities - for (int j = 0; j < NB_BASIC_ABILITIES; j++){ - if (attribute.find(MTGBasicAbilities[j]) != string::npos){ - attributefound = 1; - if (minus){ - cd->basicAbilities[j] = -1; - }else{ - cd->basicAbilities[j] = 1; - } - } - } - } - } - } - if (nbminuses < 2){ -#ifdef WIN32 - OutputDebugString("Switching to OR\n"); -#endif - cd->mode = CD_OR; - } - typeName = typeName.substr(0,found); - } - //X targets allowed ? - if (typeName.at(typeName.length()-1) == 's'){ - typeName = typeName.substr(0,typeName.length()-1); - maxtargets = -1; - } - if (cd){ - if (!tc){ - if (typeName.compare("*")!=0) cd->setSubtype(typeName); - tc = NEW DescriptorTargetChooser(cd,zones,nbzones,card,maxtargets); -#ifdef WIN32 - OutputDebugString("Advanced Attributes 2 \n"); -#endif - }else{ - return NULL; - } - }else{ - if (!tc){ - if (typeName.compare("*")==0){ - return NEW TargetZoneChooser(zones, nbzones,card, maxtargets); - }else{ - tc = NEW TypeTargetChooser(typeName.c_str(), zones, nbzones, card,maxtargets); - } - }else{ - ((TypeTargetChooser *)tc)->addType(typeName.c_str()); - tc->maxtargets = maxtargets; - } - } - } - return tc; - } - } - return NULL; -} - -TargetChooser * TargetChooserFactory::createTargetChooser(MTGCardInstance * card){ - int id = card->model->getId(); - string s = card->spellTargetType; - if (card->alias){ - id = card->alias; - //TODO load target as well... ? - } - TargetChooser * tc = createTargetChooser(s, card); - if (tc) return tc; - //Any target than cannot be defined automatically is determined by its id - switch (id){ - //Spell - case 1196: //CounterSpell - case 1224: //Spell blast - { -#if defined (WIN32) || defined (LINUX) - OutputDebugString ("Counter Spell !\n"); -#endif - return NEW SpellTargetChooser(card); - } - //Spell Or Permanent - case 1282: //ChaosLace - case 1152: //DeathLace - case 1358: //PureLace - case 1227: //ThoughLace - case 1257: //Lifelace - { - return NEW SpellOrPermanentTargetChooser(card); - } - //Red Spell or Permanent - case 1191: //Blue Elemental Blast - { - return NEW SpellOrPermanentTargetChooser(card,MTG_COLOR_RED); - } - //Blue Spell or Permanent - case 1312: //Red Elemental Blast - { - return NEW SpellOrPermanentTargetChooser(card,MTG_COLOR_BLUE); - } - //Damage History - case 1344: //Eye for an Eye - { - return NEW DamageTargetChooser(card,-1,1,RESOLVED_OK); - } - default: - { - return NULL; - } - } -} - - -TargetChooser::TargetChooser(MTGCardInstance * card, int _maxtargets): TargetsList(){ - forceTargetListReady = 0; - source = card; - maxtargets = _maxtargets; -} - -//Default targetter : every card can be targetted, unless it is protected from the source card -int TargetChooser::canTarget(Targetable * target){ - if (target->typeAsTarget() == TARGET_CARD){ - MTGCardInstance * card = (MTGCardInstance *) target; - if (source && card->protectedAgainst(source)) return 0; - return 1; - } - return 0; -} - - -int TargetChooser::addTarget(Targetable * target){ - if (canTarget(target) && TargetsList::addTarget(target)){ - } - -#if defined (WIN32) || defined (LINUX) - char buf[4096]; - sprintf(buf, "Nb targets : %i\n", cursor); - OutputDebugString(buf); -#endif - return targetsReadyCheck(); - - - -} - - - -int TargetChooser::ForceTargetListReady(){ - int state = targetsReadyCheck() ; - if (state == TARGET_OK){ - forceTargetListReady = 1; - } - return forceTargetListReady; -} - -int TargetChooser::targetsReadyCheck(){ - if (cursor == 0){ - return TARGET_NOK; - } - if (full()){ - return TARGET_OK_FULL; - } - if (!ready()){ - return TARGET_OK_NOT_READY; - } - return TARGET_OK; -} - -int TargetChooser::targetListSet(){ - int state = targetsReadyCheck(); - if (state == TARGET_OK_FULL || forceTargetListReady){ - return 1; - } - return 0; -} - - - -/** -Choose anything that has a given list of types -**/ -TypeTargetChooser::TypeTargetChooser(const char * _type, MTGCardInstance * card, int _maxtargets):TargetZoneChooser(card, _maxtargets){ - int id = Subtypes::subtypesList->Add(_type); - nbtypes = 0; - addType(id); - GameObserver * game = GameObserver::GetInstance(); - MTGGameZone * default_zones[] = {game->players[0]->game->inPlay, game->players[1]->game->inPlay}; - init(default_zones,2); -} - -TypeTargetChooser::TypeTargetChooser(const char * _type, MTGGameZone ** _zones, int nbzones, MTGCardInstance * card, int _maxtargets):TargetZoneChooser(card, _maxtargets){ - int id = Subtypes::subtypesList->Add(_type); - nbtypes = 0; - addType(id); - GameObserver * game = GameObserver::GetInstance(); - if (nbzones == 0){ - MTGGameZone * default_zones[] = {game->players[0]->game->inPlay, game->players[1]->game->inPlay}; - init(default_zones,2); - }else{ - init(_zones, nbzones); - } -} - -void TypeTargetChooser::addType(const char * _type){ - int id = Subtypes::subtypesList->Add(_type); - addType(id); -} - -void TypeTargetChooser::addType(int type){ - types[nbtypes] = type; - nbtypes++; -} - -int TypeTargetChooser::canTarget(Targetable * target ){ - if (target->typeAsTarget() == TARGET_CARD){ - MTGCardInstance * card = (MTGCardInstance *) target; - if (!TargetZoneChooser::canTarget(card)) return 0; - int result = 0; - for (int i= 0; i < nbtypes; i++){ - result += card->hasSubtype(types[i]); - } - return result; - } - return 0; -} - +#include "../include/debug.h" +#include "../include/TargetChooser.h" +#include "../include/CardDescriptor.h" +#include "../include/MTGGameZones.h" +#include "../include/GameObserver.h" +#include "../include/Subtypes.h" -/** -A Target Chooser associated to a Card Descriptor object, for fine tuning of targets description + + +TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInstance * card){ + GameObserver * game = GameObserver::GetInstance(); + MTGGameZone * zones[10]; + int nbzones = 0; + int size = s.size(); + if (size != 0){ + unsigned int found; + found = s.find("player"); + if (found != string::npos){ + int maxtargets = 1; + unsigned int several = s.find_first_of('s',5); + if (several != string::npos) maxtargets = -1; + found = s.find("creature"); + if (found != string::npos){ + return NEW DamageableTargetChooser(card,maxtargets); //Any Damageable target (player, creature) + }else{ + return NEW PlayerTargetChooser(card,maxtargets); //Any player + } + }else{ + string s1; + found = s.find("|"); + if (found != string::npos){ + string s2; + s1 = s.substr(0,found); + s2 = s.substr(found+1); + while(s2.size()){ + found = s2.find(","); + string zoneName; + if (found != string::npos){ + zoneName = s2.substr(0,found); + s2 = s2.substr(found+1); + }else{ + zoneName = s2; + s2 = ""; + } + //Graveyards + if (zoneName.compare("mygraveyard") == 0){ + zones[nbzones] = game->currentlyActing()->game->graveyard; + }else if(zoneName.compare("opponentgraveyard") == 0){ + zones[nbzones] = game->currentlyActing()->opponent()->game->graveyard; + }else if(zoneName.compare("graveyard") == 0){ + zones[nbzones] = game->players[0]->game->graveyard; + nbzones++; + zones[nbzones] = game->players[1]->game->graveyard; + }else{ + + //inPlay + if (zoneName.compare("myinplay") == 0){ + zones[nbzones] = game->currentlyActing()->game->inPlay; + }else if(zoneName.compare("opponentinplay") == 0){ + zones[nbzones] = game->currentlyActing()->opponent()->game->inPlay; + }else if(zoneName.compare("inplay") == 0){ + zones[nbzones] = game->players[0]->game->inPlay; + nbzones++; + zones[nbzones] = game->players[1]->game->inPlay; + }else{ + zones[nbzones] = game->currentlyActing()->game->inPlay; + } + } + nbzones++; + } + }else{ + s1 = s; + nbzones = 2; + zones[0]= game->players[0]->game->inPlay; + zones[1]= game->players[1]->game->inPlay; + } + + TargetChooser * tc = NULL; + int maxtargets = 1; + CardDescriptor * cd = NULL; + + while(s1.size()){ + found = s1.find(","); + string typeName; + if (found != string::npos){ + typeName = s1.substr(0,found); + s1 = s1.substr(found+1); + }else{ + typeName = s1; + s1 = ""; + } + + //Advanced cards caracteristics ? + found = typeName.find("["); + if (found != string::npos){ + int nbminuses = 0; + int end = typeName.find("]"); +#ifdef WIN32 + OutputDebugString("Advanced Attributes 1 \n"); +#endif + string attributes = typeName.substr(found+1,end-found-1); +#ifdef WIN32 + OutputDebugString(attributes.c_str()); + OutputDebugString("\n"); +#endif + cd = NEW CardDescriptor(); + while(attributes.size()){ + unsigned int found2 = attributes.find(";"); + string attribute; + if (found2 != string::npos){ + attribute = attributes.substr(0,found2); + attributes = attributes.substr(found2+1); + }else{ + attribute = attributes; + attributes = ""; + } + int minus = 0; + if (attribute[0] == '-'){ +#ifdef WIN32 + OutputDebugString("MINUS\n"); +#endif + minus = 1; + nbminuses++; + } +#ifdef WIN32 + OutputDebugString(attribute.c_str()); + OutputDebugString("\n"); +#endif + //Attacker + if (attribute.find("attacking") != string::npos){ + if (minus){ + cd->attacker = -1; + }else{ + cd->attacker = 1; + } + + //Blocker + }else if (attribute.find("blocking") != string::npos){ + if (minus){ + cd->defenser = (MTGCardInstance *)-1; //Oh yeah, that's ugly.... + }else{ + cd->defenser = (MTGCardInstance *)1; + } + + //Tapped, untapped + }else if (attribute.find("tapped") != string::npos){ + if (minus){ + cd->tapped = -1; + }else{ + cd->tapped = 1; + } + }else{ + int attributefound = 0; + //Colors + for (int cid = 0; cid < MTG_NB_COLORS; cid++){ + if (attribute.find(MTGColorStrings[cid]) != string::npos){ + attributefound = 1; + if (minus){ + cd->colors[cid] = -1; + }else{ + cd->colors[cid] = 1; + } + } + } + if (!attributefound){ + //Abilities + for (int j = 0; j < NB_BASIC_ABILITIES; j++){ + if (attribute.find(MTGBasicAbilities[j]) != string::npos){ + attributefound = 1; + if (minus){ + cd->basicAbilities[j] = -1; + }else{ + cd->basicAbilities[j] = 1; + } + } + } + } + } + } + if (nbminuses < 2){ +#ifdef WIN32 + OutputDebugString("Switching to OR\n"); +#endif + cd->mode = CD_OR; + } + typeName = typeName.substr(0,found); + } + //X targets allowed ? + if (typeName.at(typeName.length()-1) == 's'){ + typeName = typeName.substr(0,typeName.length()-1); + maxtargets = -1; + } + if (cd){ + if (!tc){ + if (typeName.compare("*")!=0) cd->setSubtype(typeName); + tc = NEW DescriptorTargetChooser(cd,zones,nbzones,card,maxtargets); +#ifdef WIN32 + OutputDebugString("Advanced Attributes 2 \n"); +#endif + }else{ + return NULL; + } + }else{ + if (!tc){ + if (typeName.compare("*")==0){ + return NEW TargetZoneChooser(zones, nbzones,card, maxtargets); + }else{ + tc = NEW TypeTargetChooser(typeName.c_str(), zones, nbzones, card,maxtargets); + } + }else{ + ((TypeTargetChooser *)tc)->addType(typeName.c_str()); + tc->maxtargets = maxtargets; + } + } + } + return tc; + } + } + return NULL; +} + +TargetChooser * TargetChooserFactory::createTargetChooser(MTGCardInstance * card){ + int id = card->model->getId(); + string s = card->spellTargetType; + if (card->alias){ + id = card->alias; + //TODO load target as well... ? + } + TargetChooser * tc = createTargetChooser(s, card); + if (tc) return tc; + //Any target than cannot be defined automatically is determined by its id + switch (id){ + //Spell + case 1196: //CounterSpell + case 1224: //Spell blast + { +#if defined (WIN32) || defined (LINUX) + OutputDebugString ("Counter Spell !\n"); +#endif + return NEW SpellTargetChooser(card); + } + //Spell Or Permanent + case 1282: //ChaosLace + case 1152: //DeathLace + case 1358: //PureLace + case 1227: //ThoughLace + case 1257: //Lifelace + { + return NEW SpellOrPermanentTargetChooser(card); + } + //Red Spell or Permanent + case 1191: //Blue Elemental Blast + { + return NEW SpellOrPermanentTargetChooser(card,MTG_COLOR_RED); + } + //Blue Spell or Permanent + case 1312: //Red Elemental Blast + { + return NEW SpellOrPermanentTargetChooser(card,MTG_COLOR_BLUE); + } + //Damage History + case 1344: //Eye for an Eye + { + return NEW DamageTargetChooser(card,-1,1,RESOLVED_OK); + } + default: + { + return NULL; + } + } +} + + +TargetChooser::TargetChooser(MTGCardInstance * card, int _maxtargets): TargetsList(){ + forceTargetListReady = 0; + source = card; + maxtargets = _maxtargets; +} + +//Default targetter : every card can be targetted, unless it is protected from the source card +int TargetChooser::canTarget(Targetable * target){ + if (target->typeAsTarget() == TARGET_CARD){ + MTGCardInstance * card = (MTGCardInstance *) target; + if (source && card->protectedAgainst(source)) return 0; + return 1; + } + return 0; +} + + +int TargetChooser::addTarget(Targetable * target){ + if (canTarget(target) && TargetsList::addTarget(target)){ + } + +#if defined (WIN32) || defined (LINUX) + char buf[4096]; + sprintf(buf, "Nb targets : %i\n", cursor); + OutputDebugString(buf); +#endif + return targetsReadyCheck(); + + + +} + + + +int TargetChooser::ForceTargetListReady(){ + int state = targetsReadyCheck() ; + if (state == TARGET_OK){ + forceTargetListReady = 1; + } + return forceTargetListReady; +} + +int TargetChooser::targetsReadyCheck(){ + if (cursor == 0){ + return TARGET_NOK; + } + if (full()){ + return TARGET_OK_FULL; + } + if (!ready()){ + return TARGET_OK_NOT_READY; + } + return TARGET_OK; +} + +int TargetChooser::targetListSet(){ + int state = targetsReadyCheck(); + if (state == TARGET_OK_FULL || forceTargetListReady){ + return 1; + } + return 0; +} + + + +/** + Choose anything that has a given list of types +**/ +TypeTargetChooser::TypeTargetChooser(const char * _type, MTGCardInstance * card, int _maxtargets):TargetZoneChooser(card, _maxtargets){ + int id = Subtypes::subtypesList->Add(_type); + nbtypes = 0; + addType(id); + GameObserver * game = GameObserver::GetInstance(); + MTGGameZone * default_zones[] = {game->players[0]->game->inPlay, game->players[1]->game->inPlay}; + init(default_zones,2); +} + +TypeTargetChooser::TypeTargetChooser(const char * _type, MTGGameZone ** _zones, int nbzones, MTGCardInstance * card, int _maxtargets):TargetZoneChooser(card, _maxtargets){ + int id = Subtypes::subtypesList->Add(_type); + nbtypes = 0; + addType(id); + GameObserver * game = GameObserver::GetInstance(); + if (nbzones == 0){ + MTGGameZone * default_zones[] = {game->players[0]->game->inPlay, game->players[1]->game->inPlay}; + init(default_zones,2); + }else{ + init(_zones, nbzones); + } +} + +void TypeTargetChooser::addType(const char * _type){ + int id = Subtypes::subtypesList->Add(_type); + addType(id); +} + +void TypeTargetChooser::addType(int type){ + types[nbtypes] = type; + nbtypes++; +} + +int TypeTargetChooser::canTarget(Targetable * target ){ + if (target->typeAsTarget() == TARGET_CARD){ + MTGCardInstance * card = (MTGCardInstance *) target; + if (!TargetZoneChooser::canTarget(card)) return 0; + int result = 0; + for (int i= 0; i < nbtypes; i++){ + result += card->hasSubtype(types[i]); + } + return result; + } + return 0; +} + + +/** + A Target Chooser associated to a Card Descriptor object, for fine tuning of targets description **/ DescriptorTargetChooser::DescriptorTargetChooser(CardDescriptor * _cd, MTGCardInstance * card, int _maxtargets):TargetZoneChooser(card, _maxtargets){ - GameObserver * game = GameObserver::GetInstance(); - MTGGameZone * default_zones[] = {game->players[0]->game->inPlay, game->players[1]->game->inPlay}; - init(default_zones,2); - cd = _cd; + GameObserver * game = GameObserver::GetInstance(); + MTGGameZone * default_zones[] = {game->players[0]->game->inPlay, game->players[1]->game->inPlay}; + init(default_zones,2); + cd = _cd; } DescriptorTargetChooser::DescriptorTargetChooser(CardDescriptor * _cd, MTGGameZone ** _zones, int nbzones, MTGCardInstance * card, int _maxtargets):TargetZoneChooser(card, _maxtargets){ - GameObserver * game = GameObserver::GetInstance(); - if (nbzones == 0){ - MTGGameZone * default_zones[] = {game->players[0]->game->inPlay, game->players[1]->game->inPlay}; - init(default_zones,2); - }else{ - init(_zones, nbzones); - } - cd = _cd; + GameObserver * game = GameObserver::GetInstance(); + if (nbzones == 0){ + MTGGameZone * default_zones[] = {game->players[0]->game->inPlay, game->players[1]->game->inPlay}; + init(default_zones,2); + }else{ + init(_zones, nbzones); + } + cd = _cd; } int DescriptorTargetChooser::canTarget(Targetable * target){ - if (target->typeAsTarget() == TARGET_CARD){ - MTGCardInstance * card = (MTGCardInstance *) target; - if (!TargetZoneChooser::canTarget(card)) return 0; - if (cd->match(card)) return 1; - } - return 0; + if (target->typeAsTarget() == TARGET_CARD){ + MTGCardInstance * card = (MTGCardInstance *) target; + if (!TargetZoneChooser::canTarget(card)) return 0; + if (cd->match(card)) return 1; + } + return 0; +} + + + +/** + Choose a creature +**/ + +CreatureTargetChooser::CreatureTargetChooser( MTGCardInstance * card, int _maxtargets):TargetZoneChooser(card, _maxtargets){ + GameObserver * game = GameObserver::GetInstance(); + MTGGameZone * default_zones[] = {game->players[0]->game->inPlay, game->players[1]->game->inPlay}; + init(default_zones,2); + maxpower= -1; + maxtoughness= -1; +} + +CreatureTargetChooser::CreatureTargetChooser(MTGGameZone ** _zones, int nbzones, MTGCardInstance * card, int _maxtargets):TargetZoneChooser(card, _maxtargets){ + GameObserver * game = GameObserver::GetInstance(); + if (nbzones == 0){ + MTGGameZone * default_zones[] = {game->players[0]->game->inPlay, game->players[1]->game->inPlay}; + init(default_zones,2); + }else{ + init(_zones, nbzones); + } + maxpower = -1; + maxtoughness= -1; +} + + +int CreatureTargetChooser::canTarget(Targetable * target){ + if (!TargetZoneChooser::canTarget(target)) return 0; + if (target->typeAsTarget() == TARGET_CARD){ + MTGCardInstance * card = (MTGCardInstance *) target; + if (maxpower != -1 && card->power > maxpower) return 0; + if (maxtoughness != -1 && card->toughness > maxtoughness) return 0; + return card->isACreature(); + } + return 0; +} + + +TargetZoneChooser::TargetZoneChooser(MTGCardInstance * card, int _maxtargets){ + init(NULL,0); + source = card; + maxtargets = _maxtargets; +} + +TargetZoneChooser::TargetZoneChooser(MTGGameZone ** _zones, int _nbzones,MTGCardInstance * card, int _maxtargets){ + init(_zones, _nbzones); + source = card; + maxtargets = _maxtargets; +} + +int TargetZoneChooser::init(MTGGameZone ** _zones, int _nbzones){ + for (int i = 0; i < _nbzones; i++){ + zones[i] = _zones[i]; + } + nbzones = _nbzones; + return nbzones; +} + +int TargetZoneChooser::canTarget(Targetable * target){ + if (!TargetChooser::canTarget(target)) return 0; + if (target->typeAsTarget() == TARGET_CARD){ + MTGCardInstance * card = (MTGCardInstance *) target; + for (int i = 0; ihasCard(card)) return 1; + } + } + return 0; +} + + +/* Player Target */ +int PlayerTargetChooser::canTarget(Targetable * target){ + if (target->typeAsTarget() == TARGET_PLAYER){ + return 1; + } + return 0; +} + +/*Damageable Target */ +int DamageableTargetChooser::canTarget(Targetable * target){ + if (target->typeAsTarget() == TARGET_PLAYER){ +#if defined (WIN32) || defined (LINUX) + OutputDebugString("Targetting Player !!!\n"); +#endif + return 1; + } + return CreatureTargetChooser::canTarget(target); +} + + +/*Spell */ + + + +SpellTargetChooser::SpellTargetChooser(MTGCardInstance * card,int _color, int _maxtargets ):TargetChooser(card, _maxtargets){ + color = _color; +} + +int SpellTargetChooser::canTarget(Targetable * target){ + MTGCardInstance * card = NULL; + if (target->typeAsTarget() == TARGET_STACKACTION){ + Interruptible * action = (Interruptible *) target; + if (action->type == ACTION_SPELL && action->state==NOT_RESOLVED){ + Spell * spell = (Spell *) action; + card = spell->source; + if (card && (color == -1 || card->hasColor(color))) return 1; + } + } + + return 0; + +} + + +/*Spell or Permanent */ +SpellOrPermanentTargetChooser::SpellOrPermanentTargetChooser(MTGCardInstance * card,int _color, int _maxtargets):TargetZoneChooser(card, _maxtargets){ + GameObserver * game = GameObserver::GetInstance(); + MTGGameZone * default_zones[] = {game->players[0]->game->inPlay, game->players[1]->game->inPlay}; + init(default_zones,2); + color = _color; +} + +int SpellOrPermanentTargetChooser::canTarget(Targetable * target){ + MTGCardInstance * card = NULL; + if (target->typeAsTarget() == TARGET_CARD){ + card = (MTGCardInstance *) target; + if (color == -1 || card->hasColor(color)) return TargetZoneChooser::canTarget(target); + }else if (target->typeAsTarget() == TARGET_STACKACTION){ + Interruptible * action = (Interruptible *) target; + if (action->type == ACTION_SPELL && action->state==NOT_RESOLVED){ + Spell * spell = (Spell *) action; + card = spell->source; + if (card && (color == -1 || card->hasColor(color))) return 1; + } + } + + return 0; + +} + + + +/*Damage */ +DamageTargetChooser::DamageTargetChooser(MTGCardInstance * card,int _color, int _maxtargets, int _state):TargetChooser(card, _maxtargets){ + color = _color; + state = _state; +} + +int DamageTargetChooser::canTarget(Targetable * target){ + MTGCardInstance * card = NULL; + if (target->typeAsTarget() == TARGET_STACKACTION){ + Interruptible * action = (Interruptible *) target; + if (action->type == ACTION_DAMAGE && (action->state == state || state == -1)){ + Damage * damage = (Damage *) action; + card = damage->source; + if (card && (color == -1 || card->hasColor(color))) return 1; + } + } + + return 0; + +} + + +/*Damage or Permanent */ +DamageOrPermanentTargetChooser::DamageOrPermanentTargetChooser(MTGCardInstance * card,int _color, int _maxtargets):TargetZoneChooser(card, _maxtargets){ + GameObserver * game = GameObserver::GetInstance(); + MTGGameZone * default_zones[] = {game->players[0]->game->inPlay, game->players[1]->game->inPlay}; + init(default_zones,2); + color = _color; +} + +int DamageOrPermanentTargetChooser::canTarget(Targetable * target){ + MTGCardInstance * card = NULL; + if (target->typeAsTarget() == TARGET_CARD){ + card = (MTGCardInstance *) target; + if (color == -1 || card->hasColor(color)) return TargetZoneChooser::canTarget(target); + }else if (target->typeAsTarget() == TARGET_STACKACTION){ + Interruptible * action = (Interruptible *) target; + if (action->type == ACTION_DAMAGE){ + Damage * damage = (Damage *) action; + card = damage->source; + if (card && (color == -1 || card->hasColor(color))) return 1; + } + } + + return 0; + } - - - -/** -Choose a creature -**/ - -CreatureTargetChooser::CreatureTargetChooser( MTGCardInstance * card, int _maxtargets):TargetZoneChooser(card, _maxtargets){ - GameObserver * game = GameObserver::GetInstance(); - MTGGameZone * default_zones[] = {game->players[0]->game->inPlay, game->players[1]->game->inPlay}; - init(default_zones,2); - maxpower= -1; - maxtoughness= -1; -} - -CreatureTargetChooser::CreatureTargetChooser(MTGGameZone ** _zones, int nbzones, MTGCardInstance * card, int _maxtargets):TargetZoneChooser(card, _maxtargets){ - GameObserver * game = GameObserver::GetInstance(); - if (nbzones == 0){ - MTGGameZone * default_zones[] = {game->players[0]->game->inPlay, game->players[1]->game->inPlay}; - init(default_zones,2); - }else{ - init(_zones, nbzones); - } - maxpower = -1; - maxtoughness= -1; -} - - -int CreatureTargetChooser::canTarget(Targetable * target){ - if (!TargetZoneChooser::canTarget(target)) return 0; - if (target->typeAsTarget() == TARGET_CARD){ - MTGCardInstance * card = (MTGCardInstance *) target; - if (maxpower != -1 && card->power > maxpower) return 0; - if (maxtoughness != -1 && card->toughness > maxtoughness) return 0; - return card->isACreature(); - } - return 0; -} - - -TargetZoneChooser::TargetZoneChooser(MTGCardInstance * card, int _maxtargets){ - init(NULL,0); - source = card; - maxtargets = _maxtargets; -} - -TargetZoneChooser::TargetZoneChooser(MTGGameZone ** _zones, int _nbzones,MTGCardInstance * card, int _maxtargets){ - init(_zones, _nbzones); - source = card; - maxtargets = _maxtargets; -} - -int TargetZoneChooser::init(MTGGameZone ** _zones, int _nbzones){ - for (int i = 0; i < _nbzones; i++){ - zones[i] = _zones[i]; - } - nbzones = _nbzones; - return nbzones; -} - -int TargetZoneChooser::canTarget(Targetable * target){ - if (!TargetChooser::canTarget(target)) return 0; - if (target->typeAsTarget() == TARGET_CARD){ - MTGCardInstance * card = (MTGCardInstance *) target; - for (int i = 0; ihasCard(card)) return 1; - } - } - return 0; -} - - -/* Player Target */ -int PlayerTargetChooser::canTarget(Targetable * target){ - if (target->typeAsTarget() == TARGET_PLAYER){ - return 1; - } - return 0; -} - -/*Damageable Target */ -int DamageableTargetChooser::canTarget(Targetable * target){ - if (target->typeAsTarget() == TARGET_PLAYER){ -#if defined (WIN32) || defined (LINUX) - OutputDebugString("Targetting Player !!!\n"); -#endif - return 1; - } - return CreatureTargetChooser::canTarget(target); -} - - -/*Spell */ - - - -SpellTargetChooser::SpellTargetChooser(MTGCardInstance * card,int _color, int _maxtargets ):TargetChooser(card, _maxtargets){ - color = _color; -} - -int SpellTargetChooser::canTarget(Targetable * target){ - MTGCardInstance * card = NULL; - if (target->typeAsTarget() == TARGET_STACKACTION){ - Interruptible * action = (Interruptible *) target; - if (action->type == ACTION_SPELL && action->state==NOT_RESOLVED){ - Spell * spell = (Spell *) action; - card = spell->source; - if (card && (color == -1 || card->hasColor(color))) return 1; - } - } - - return 0; - -} - - -/*Spell or Permanent */ -SpellOrPermanentTargetChooser::SpellOrPermanentTargetChooser(MTGCardInstance * card,int _color, int _maxtargets):TargetZoneChooser(card, _maxtargets){ - GameObserver * game = GameObserver::GetInstance(); - MTGGameZone * default_zones[] = {game->players[0]->game->inPlay, game->players[1]->game->inPlay}; - init(default_zones,2); - color = _color; -} - -int SpellOrPermanentTargetChooser::canTarget(Targetable * target){ - MTGCardInstance * card = NULL; - if (target->typeAsTarget() == TARGET_CARD){ - card = (MTGCardInstance *) target; - if (color == -1 || card->hasColor(color)) return TargetZoneChooser::canTarget(target); - }else if (target->typeAsTarget() == TARGET_STACKACTION){ - Interruptible * action = (Interruptible *) target; - if (action->type == ACTION_SPELL && action->state==NOT_RESOLVED){ - Spell * spell = (Spell *) action; - card = spell->source; - if (card && (color == -1 || card->hasColor(color))) return 1; - } - } - - return 0; - -} - - - -/*Damage */ -DamageTargetChooser::DamageTargetChooser(MTGCardInstance * card,int _color, int _maxtargets, int _state):TargetChooser(card, _maxtargets){ - color = _color; - state = _state; -} - -int DamageTargetChooser::canTarget(Targetable * target){ - MTGCardInstance * card = NULL; - if (target->typeAsTarget() == TARGET_STACKACTION){ - Interruptible * action = (Interruptible *) target; - if (action->type == ACTION_DAMAGE && (action->state == state || state == -1)){ - Damage * damage = (Damage *) action; - card = damage->source; - if (card && (color == -1 || card->hasColor(color))) return 1; - } - } - - return 0; - -} - - -/*Damage or Permanent */ -DamageOrPermanentTargetChooser::DamageOrPermanentTargetChooser(MTGCardInstance * card,int _color, int _maxtargets):TargetZoneChooser(card, _maxtargets){ - GameObserver * game = GameObserver::GetInstance(); - MTGGameZone * default_zones[] = {game->players[0]->game->inPlay, game->players[1]->game->inPlay}; - init(default_zones,2); - color = _color; -} - -int DamageOrPermanentTargetChooser::canTarget(Targetable * target){ - MTGCardInstance * card = NULL; - if (target->typeAsTarget() == TARGET_CARD){ - card = (MTGCardInstance *) target; - if (color == -1 || card->hasColor(color)) return TargetZoneChooser::canTarget(target); - }else if (target->typeAsTarget() == TARGET_STACKACTION){ - Interruptible * action = (Interruptible *) target; - if (action->type == ACTION_DAMAGE){ - Damage * damage = (Damage *) action; - card = damage->source; - if (card && (color == -1 || card->hasColor(color))) return 1; - } - } - - return 0; - -} diff --git a/projects/mtg/src/TargetsList.cpp b/projects/mtg/src/TargetsList.cpp index b88616bd0..cbcdc606b 100644 --- a/projects/mtg/src/TargetsList.cpp +++ b/projects/mtg/src/TargetsList.cpp @@ -1,129 +1,129 @@ -#include "../include/debug.h" -#include "../include/TargetsList.h" -#include "../include/Player.h" -#include "../include/MTGCardInstance.h" -#include "../include/Damage.h" -#include "../include/ActionStack.h" - -TargetsList::TargetsList(){ - cursor = 0; -} - -TargetsList::TargetsList(Targetable * _targets[], int nbtargets){ - for (int i = 0; i < nbtargets; i++){ - targets[i] = _targets[i]; - } - cursor = nbtargets; -} - -int TargetsList::addTarget(Targetable * target){ - if (!alreadyHasTarget(target)){ - targets[cursor] = target; - cursor++; - return 1; - } - return 0; - -} - - -int TargetsList::alreadyHasTarget(Targetable * target){ - for (int i=0; itypeAsTarget() == type){ - return (targets[i]); - } - if (targets[i] == previous) found = 1; - } - return NULL; -} - +#include "../include/debug.h" +#include "../include/TargetsList.h" +#include "../include/Player.h" +#include "../include/MTGCardInstance.h" +#include "../include/Damage.h" +#include "../include/ActionStack.h" + +TargetsList::TargetsList(){ + cursor = 0; +} + +TargetsList::TargetsList(Targetable * _targets[], int nbtargets){ + for (int i = 0; i < nbtargets; i++){ + targets[i] = _targets[i]; + } + cursor = nbtargets; +} + +int TargetsList::addTarget(Targetable * target){ + if (!alreadyHasTarget(target)){ + targets[cursor] = target; + cursor++; + return 1; + } + return 0; + +} + + +int TargetsList::alreadyHasTarget(Targetable * target){ + for (int i=0; itypeAsTarget() == type){ + return (targets[i]); + } + if (targets[i] == previous) found = 1; + } + return NULL; +} + MTGCardInstance * TargetsList::getNextCardTarget(MTGCardInstance * previous){ - return ((MTGCardInstance *)getNextTarget(previous, TARGET_CARD)); + return ((MTGCardInstance *)getNextTarget(previous, TARGET_CARD)); } - + Player * TargetsList::getNextPlayerTarget(Player * previous){ - return ((Player *)getNextTarget(previous, TARGET_PLAYER)); + return ((Player *)getNextTarget(previous, TARGET_PLAYER)); +} + + +Interruptible * TargetsList::getNextInterruptible(Interruptible * previous, int type){ + int found = 0; + if (!previous) found = 1; + for (int i = 0; i < cursor; i++){ + if (found && targets[i]->typeAsTarget() == TARGET_STACKACTION){ + Interruptible * action = (Interruptible *) targets[i]; + if (action->type==type){ + return action; + } + } + if (targets[i] == previous) found = 1; + } + return NULL; } - -Interruptible * TargetsList::getNextInterruptible(Interruptible * previous, int type){ - int found = 0; - if (!previous) found = 1; - for (int i = 0; i < cursor; i++){ - if (found && targets[i]->typeAsTarget() == TARGET_STACKACTION){ - Interruptible * action = (Interruptible *) targets[i]; - if (action->type==type){ - return action; - } - } - if (targets[i] == previous) found = 1; - } - return NULL; -} - Spell * TargetsList::getNextSpellTarget(Spell * previous){ - Spell * spell = (Spell *) getNextInterruptible(previous, ACTION_SPELL); - return spell; + Spell * spell = (Spell *) getNextInterruptible(previous, ACTION_SPELL); + return spell; } //How about DAMAGESTacks ?? Damage * TargetsList::getNextDamageTarget(Damage * previous){ - Damage * damage = (Damage * ) getNextInterruptible(previous, ACTION_DAMAGE); - return damage; + Damage * damage = (Damage * ) getNextInterruptible(previous, ACTION_DAMAGE); + return damage; } Damageable * TargetsList::getNextDamageableTarget(Damageable * previous){ - int found = 0; - if (!previous) found = 1; - for (int i = 0; i < cursor; i++){ + int found = 0; + if (!previous) found = 1; + for (int i = 0; i < cursor; i++){ - if (targets[i]->typeAsTarget() == TARGET_PLAYER){ - if (found){ - return ((Player *) targets[i]); - }else{ - if ((Player *)targets[i] == previous) found = 1; - } - }else if(targets[i]->typeAsTarget() == TARGET_CARD){ - if (found){ - return ((MTGCardInstance *) targets[i]); - }else{ - if ((MTGCardInstance *)targets[i] == previous) found = 1; - } - } - } - return NULL; -} \ No newline at end of file + if (targets[i]->typeAsTarget() == TARGET_PLAYER){ + if (found){ + return ((Player *) targets[i]); + }else{ + if ((Player *)targets[i] == previous) found = 1; + } + }else if(targets[i]->typeAsTarget() == TARGET_CARD){ + if (found){ + return ((MTGCardInstance *) targets[i]); + }else{ + if ((MTGCardInstance *)targets[i] == previous) found = 1; + } + } + } + return NULL; +} diff --git a/projects/mtg/src/TestSuiteAI.cpp b/projects/mtg/src/TestSuiteAI.cpp index df4d7e5d4..9c2b045c5 100644 --- a/projects/mtg/src/TestSuiteAI.cpp +++ b/projects/mtg/src/TestSuiteAI.cpp @@ -1,471 +1,471 @@ -#include "../include/TestSuiteAI.h" -#include "../include/debug.h" - -#include -using std::string; - -TestSuiteAI::TestSuiteAI(MTGAllCards* collection, TestSuite * _suite, int playerId):AIPlayer(_suite->buildDeck(collection, playerId),"testsuite"){ - suite = _suite; - timer= 0; - mAvatarTex = JRenderer::GetInstance()->LoadTexture("ai/baka/avatar.jpg", TEX_TYPE_USE_VRAM); - if (mAvatarTex){ - mAvatar = NEW JQuad(mAvatarTex, 0, 0, 35, 50); - } -} - -MTGCardInstance * TestSuite::getCardByMTGId(int mtgid){ - GameObserver * g = GameObserver::GetInstance(); - for (int i = 0; i < 2; i++){ - Player * p = g->players[i]; - MTGGameZone * zones[] = {p->game->library,p->game->hand, p->game->inPlay, p->game->graveyard}; - for (int j = 0; j < 4; j++){ - MTGGameZone * zone = zones[j]; - for (int k = 0; k < zone->nb_cards; k++){ - MTGCardInstance * card = zone->cards[k]; - if (!card) OutputDebugString ("wtf ?"); - if (card->getMTGId() == mtgid) return card; - } - } - } - return NULL; -} - -Interruptible * TestSuite::getActionByMTGId(int mtgid){ - ActionStack * as= GameObserver::GetInstance()->mLayers->stackLayer(); - Interruptible * action = NULL; - while ((action = as->getNext(action,0,0,1))){ - if (action->source && action->source->getMTGId() == mtgid){ - return action; - } - } - return NULL; -} - -int TestSuiteAI::Act(float dt){ - GameObserver * g = GameObserver::GetInstance(); - g->gameOver = NULL; // Prevent draw rule from losing the game - timer+= dt; - if (timer < suite->timerLimit) return 1; - timer = 0; - string action = suite->getNextAction(); - if (g->mLayers->stackLayer()->askIfWishesToInterrupt == this){ - if(action.compare("no") != 0 && action.compare("yes") != 0){ - g->mLayers->stackLayer()->cancelInterruptOffer(); - suite->currentAction--; - return 1; - } - } - - if (action == ""){ - //end of game - suite->assertGame(); - g->gameOver = g->players[0]; - return 1; - } - if (action.compare("eot")== 0){ - if (g->getCurrentGamePhase() != MTG_PHASE_CLEANUP) suite->currentAction--; - g->userRequestNextGamePhase(); - } - else if (action.compare("next")==0){ - g->userRequestNextGamePhase(); - }else if (action.compare("yes")==0){ - g->mLayers->stackLayer()->setIsInterrupting(this); - }else if (action.compare("endinterruption")==0){ - g->mLayers->stackLayer()->endOfInterruption(); - }else if(action.compare("no")==0){ - if (g->mLayers->stackLayer()->askIfWishesToInterrupt == this){ - g->mLayers->stackLayer()->cancelInterruptOffer(); - } - }else{ - int mtgid = atoi(action.c_str()); - if (mtgid){ - MTGCardInstance * card = suite->getCardByMTGId(mtgid); - if (card) { - g->cardClick(card); - }else{ - Interruptible * action = suite->getActionByMTGId(mtgid); - if (action){ - g->stackObjectClicked(action); - } - } - }else{ - return 0; - } - } - return 1; -} - - -TestSuiteActions::TestSuiteActions(){ - nbitems = 0; -} - -void TestSuiteActions::add(string s){ - actions[nbitems] = s; - nbitems++; -} - -TestSuitePlayerData::TestSuitePlayerData(){ - life = 20; - manapool = NEW ManaCost(); -} - -TestSuitePlayerData::~TestSuitePlayerData(){ - SAFE_DELETE(manapool); -} - -TestSuitePlayerZone::TestSuitePlayerZone(){ - nbitems = 0; -} - -void TestSuitePlayerZone::add(int cardId){ - cards[nbitems] = cardId; - nbitems++; -} - -TestSuiteState::TestSuiteState(){ - -} - -void TestSuiteState::parsePlayerState(int playerId, string s){ - unsigned int limiter = s.find(":"); - string areaS; - int area; - if (limiter != string::npos){ - areaS = s.substr(0,limiter); - if (areaS.compare("graveyard") == 0){ - area = 0; - }else if(areaS.compare("library") == 0){ - area = 1; - }else if(areaS.compare("hand") == 0){ - area = 2; - }else if(areaS.compare("inplay") == 0 ){ - area = 3; - }else if(areaS.compare("life") == 0){ - playerData[playerId].life = atoi((s.substr(limiter+1)).c_str()); - return; - }else if(areaS.compare("manapool") == 0){ - SAFE_DELETE(playerData[playerId].manapool); - playerData[playerId].manapool = ManaCost::parseManaCost(s.substr(limiter+1)); - return; - }else{ - return; // ERROR - } - s = s.substr(limiter+1); - while (s.size()){ - unsigned int value; - limiter = s.find(","); - if (limiter != string::npos){ - value = atoi(s.substr(0,limiter).c_str()); - s = s.substr(limiter+1); - }else{ - value = atoi(s.c_str()); - s = ""; - } - playerData[playerId].zones[area].add(value); - } - }else{ - //ERROR - } -} - - -string TestSuite::getNextAction(){ - if (actions.nbitems && currentAction < actions.nbitems){ - currentAction++; - return actions.actions[currentAction-1]; - } - return ""; -} - - -MTGPlayerCards * TestSuite::buildDeck(MTGAllCards * collection, int playerId){ - char buf[4096]; - int list[100]; - int nbcards = 0; - for (int j = 0; j < 4; j++){ - for (int k = 0; k < initState.playerData[playerId].zones[j].nbitems; k++){ - int cardid = initState.playerData[playerId].zones[j].cards[k]; - list[nbcards] = cardid; - nbcards++; - } - } - MTGPlayerCards * deck = NEW MTGPlayerCards(collection, list, nbcards); - return deck; -} - -void TestSuite::initGame(){ - //The first test runs slowly, the other ones run faster. - //This way a human can see what happens when testing a specific file, - // or go faster when it comes to the whole test suite. - //Warning, putting this value too low (< 0.25) will give unexpected results - if (!timerLimit){ - timerLimit = 0.3; - }else{ - timerLimit = 0.26; - } -//Put the GameObserver in the initial state - GameObserver * g = GameObserver::GetInstance(); - OutputDebugString("Init Game\n"); - g->phaseRing->goToPhase(initState.phase, g->players[0]); - g->currentGamePhase = initState.phase; - for (int i = 0; i < 2; i++){ - Player * p = g->players[i]; - p->life = initState.playerData[i].life; - p->getManaPool()->copy(initState.playerData[i].manapool); - MTGGameZone * playerZones[] = {p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay}; - for (int j = 0; j < 4; j++){ - MTGGameZone * zone = playerZones[j]; - for (int k = 0; k < initState.playerData[i].zones[j].nbitems; k++){ - MTGCardInstance * card = getCardByMTGId(initState.playerData[i].zones[j].cards[k]); - if (card && zone != p->game->library){ - if (zone == p->game->inPlay){ - p->game->putInZone(card, p->game->library, p->game->hand); - Spell * spell = NEW Spell(card); - p->game->putInZone(card, p->game->hand, p->game->stack); - spell->resolve(); - card->summoningSickness = 0; - delete spell; - }else{ - if (!p->game->library->hasCard(card)){ - LOG ("ERROR, CARD NOT FOUND IN LIBRARY\n"); - } - p->game->putInZone(card,p->game->library,zone); - } - } - } - } - } - OutputDebugString("Init Game Done !\n"); -} - -int TestSuite::Log(const char * text){ - ofstream file ("Res/test/results.html",ios_base::app); - if (file){ - file << text; - file << "\n"; - file.close(); - } -#if defined (WIN32) || defined (LINUX) - OutputDebugString(text); - OutputDebugString("\n"); -#endif - return 1; - -} -int TestSuite::assertGame(){ -//compare the game state with the results - char result[4096]; - sprintf(result,"

%s

",files[currentfile-1].c_str()); - Log(result); - - int error = 0; - GameObserver * g = GameObserver::GetInstance(); - if (g->currentGamePhase != endState.phase){ - sprintf(result, "==phase problem. Expected %i, got %i==
",endState.phase, g->currentGamePhase); - Log(result); - error++; - } - for (int i = 0; i < 2; i++){ - Player * p = g->players[i]; - if (p->life != endState.playerData[i].life){ - sprintf(result, "==life problem for player %i. Expected %i, got %i==
",i,endState.playerData[i].life, p->life); - Log(result); - error++; - } - if (! p->getManaPool()->canAfford(endState.playerData[i].manapool)){ - sprintf(result, "==Mana problem. Was expecting %i but got %i for player %i==
",endState.playerData[i].manapool->getConvertedCost(),p->getManaPool()->getConvertedCost(),i); - Log(result); - error++; - } - if(! endState.playerData[i].manapool->canAfford(p->getManaPool())){ - sprintf(result, "==Mana problem. Was expecting %i but got %i for player %i==
",endState.playerData[i].manapool->getConvertedCost(),p->getManaPool()->getConvertedCost(),i); - Log(result); - error++; - - } - MTGGameZone * playerZones[] = {p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay}; - for (int j = 0; j < 4; j++){ - MTGGameZone * zone = playerZones[j]; - if (zone->nb_cards != endState.playerData[i].zones[j].nbitems){ - Log("==Card number not the same==
"); - error++; - return 0; - } - for (int k = 0; k < endState.playerData[i].zones[j].nbitems; k++){ - int cardid = endState.playerData[i].zones[j].cards[k]; - int realcardid = zone->cards[k]->getMTGId(); - if ( realcardid!= cardid){ - sprintf(result, "==Card ID not the same. Expected %i, got %i==
", cardid, realcardid); - Log(result); - error++; - } - } - } - } - if (error) return 0; - Log("==Test Succesful !=="); - return 1; -} - -TestSuite::TestSuite(const char * filename){ - timerLimit = 0; - std::ifstream file(filename); - std::string s; - nbfiles = 0; - currentfile = 0; - int comment = 0; - if(file){ - while(std::getline(file,s)){ - if (s[0] == '/' && s[1] == '*') comment = 1; - if (s[0] && s[0] != '#' && !comment){ - files[nbfiles] = s; - nbfiles++; - } - if (s[0] == '*' && s[1] == '/') comment = 0; - } - file.close(); - } - - ofstream file2 ("Res/test/results.html"); - if (file2){ - file2 << ""; - file2 << ""; - file2 << "\n"; - file2.close(); - } - -} - -int TestSuite::loadNext(){ - if (!nbfiles) return 0; - if (currentfile >= nbfiles) return 0; - load(files[currentfile].c_str()); - currentfile++; - return currentfile; -} - -//TODO PArses a string and gives phase numer -int TestSuite::phaseStrToInt(string s){ - if (s.compare("untap") == 0) return MTG_PHASE_UNTAP; - if (s.compare("upkeep") == 0)return MTG_PHASE_UPKEEP; -if (s.compare("draw") == 0)return MTG_PHASE_DRAW; - if (s.compare("firstmain") == 0)return MTG_PHASE_FIRSTMAIN; -if (s.compare("combatbegin") == 0)return MTG_PHASE_COMBATBEGIN; - if (s.compare("combatattackers") == 0)return MTG_PHASE_COMBATATTACKERS; - if (s.compare("combatblockers") == 0)return MTG_PHASE_COMBATBLOCKERS; -if (s.compare("combatdamage") == 0)return MTG_PHASE_COMBATDAMAGE; - if (s.compare("combatend") == 0)return MTG_PHASE_COMBATEND; -if (s.compare("secondmain") == 0)return MTG_PHASE_SECONDMAIN; -if (s.compare("endofturn") == 0)return MTG_PHASE_ENDOFTURN; -if (s.compare("cleanup") == 0)return MTG_PHASE_CLEANUP; -return -1; -} - -void TestSuiteActions::cleanup(){ - nbitems = 0; -} - -void TestSuitePlayerZone::cleanup(){ - nbitems = 0; -} - -void TestSuitePlayerData::cleanup(){ - if (manapool) delete manapool; - manapool = NULL; - manapool = NEW ManaCost(); - for (int i = 0; i < 5; i++){ - zones[i].cleanup(); - } - life=20; -} - -void TestSuiteState::cleanup(){ - for (int i = 0; i < 2; i++){ - playerData[i].cleanup(); - } -} - -void TestSuite::cleanup(){ - currentAction = 0; - initState.cleanup(); - endState.cleanup(); - actions.cleanup(); -} - -void TestSuite::load(const char * _filename){ - char filename[4096]; - sprintf(filename, "Res/test/%s", _filename); - std::ifstream file(filename); - std::string s; - - int state = -1; - - if(file){ - cleanup(); - while(std::getline(file,s)){ - std::transform( s.begin(), s.end(), s.begin(),::tolower ); - switch(state){ - case -1: - if (s.compare("[init]") == 0) state++; - break; - case 0: - if (s.compare("[player1]") == 0){ - state++; - }else{ - initState.phase = phaseStrToInt(s); - } - break; - case 1: - if (s.compare("[player2]") == 0){ - state++; - }else{ - initState.parsePlayerState(0, s); - } - break; - case 2: - if (s.compare("[do]") == 0){ - state++; - }else{ - initState.parsePlayerState(1, s); - } - break; - case 3: - if (s.compare("[assert]") == 0){ - state++; - }else{ - actions.add(s); - } - break; - case 4: - if (s.compare("[player1]") == 0){ - state++; - }else{ - endState.phase = phaseStrToInt(s); - } - break; - case 5: - if (s.compare("[player2]") == 0){ - state++; - }else{ - endState.parsePlayerState(0, s); - } - break; - case 6: - if (s.compare("[end]") == 0){ - state++; - }else{ - endState.parsePlayerState(1, s); - } - break; - } - } - file.close(); - }else{ - //TODO Error management - } -} - +#include "../include/TestSuiteAI.h" +#include "../include/debug.h" + +#include +using std::string; + +TestSuiteAI::TestSuiteAI(MTGAllCards* collection, TestSuite * _suite, int playerId):AIPlayer(_suite->buildDeck(collection, playerId),"testsuite"){ + suite = _suite; + timer= 0; + mAvatarTex = JRenderer::GetInstance()->LoadTexture("ai/baka/avatar.jpg", TEX_TYPE_USE_VRAM); + if (mAvatarTex){ + mAvatar = NEW JQuad(mAvatarTex, 0, 0, 35, 50); + } +} + +MTGCardInstance * TestSuite::getCardByMTGId(int mtgid){ + GameObserver * g = GameObserver::GetInstance(); + for (int i = 0; i < 2; i++){ + Player * p = g->players[i]; + MTGGameZone * zones[] = {p->game->library,p->game->hand, p->game->inPlay, p->game->graveyard}; + for (int j = 0; j < 4; j++){ + MTGGameZone * zone = zones[j]; + for (int k = 0; k < zone->nb_cards; k++){ + MTGCardInstance * card = zone->cards[k]; + if (!card) OutputDebugString ("wtf ?"); + if (card->getMTGId() == mtgid) return card; + } + } + } + return NULL; +} + +Interruptible * TestSuite::getActionByMTGId(int mtgid){ + ActionStack * as= GameObserver::GetInstance()->mLayers->stackLayer(); + Interruptible * action = NULL; + while ((action = as->getNext(action,0,0,1))){ + if (action->source && action->source->getMTGId() == mtgid){ + return action; + } + } + return NULL; +} + +int TestSuiteAI::Act(float dt){ + GameObserver * g = GameObserver::GetInstance(); + g->gameOver = NULL; // Prevent draw rule from losing the game + timer+= dt; + if (timer < suite->timerLimit) return 1; + timer = 0; + string action = suite->getNextAction(); + if (g->mLayers->stackLayer()->askIfWishesToInterrupt == this){ + if(action.compare("no") != 0 && action.compare("yes") != 0){ + g->mLayers->stackLayer()->cancelInterruptOffer(); + suite->currentAction--; + return 1; + } + } + + if (action == ""){ + //end of game + suite->assertGame(); + g->gameOver = g->players[0]; + return 1; + } + if (action.compare("eot")== 0){ + if (g->getCurrentGamePhase() != MTG_PHASE_CLEANUP) suite->currentAction--; + g->userRequestNextGamePhase(); + } + else if (action.compare("next")==0){ + g->userRequestNextGamePhase(); + }else if (action.compare("yes")==0){ + g->mLayers->stackLayer()->setIsInterrupting(this); + }else if (action.compare("endinterruption")==0){ + g->mLayers->stackLayer()->endOfInterruption(); + }else if(action.compare("no")==0){ + if (g->mLayers->stackLayer()->askIfWishesToInterrupt == this){ + g->mLayers->stackLayer()->cancelInterruptOffer(); + } + }else{ + int mtgid = atoi(action.c_str()); + if (mtgid){ + MTGCardInstance * card = suite->getCardByMTGId(mtgid); + if (card) { + g->cardClick(card); + }else{ + Interruptible * action = suite->getActionByMTGId(mtgid); + if (action){ + g->stackObjectClicked(action); + } + } + }else{ + return 0; + } + } + return 1; +} + + +TestSuiteActions::TestSuiteActions(){ + nbitems = 0; +} + +void TestSuiteActions::add(string s){ + actions[nbitems] = s; + nbitems++; +} + +TestSuitePlayerData::TestSuitePlayerData(){ + life = 20; + manapool = NEW ManaCost(); +} + +TestSuitePlayerData::~TestSuitePlayerData(){ + SAFE_DELETE(manapool); +} + +TestSuitePlayerZone::TestSuitePlayerZone(){ + nbitems = 0; +} + +void TestSuitePlayerZone::add(int cardId){ + cards[nbitems] = cardId; + nbitems++; +} + +TestSuiteState::TestSuiteState(){ + +} + +void TestSuiteState::parsePlayerState(int playerId, string s){ + unsigned int limiter = s.find(":"); + string areaS; + int area; + if (limiter != string::npos){ + areaS = s.substr(0,limiter); + if (areaS.compare("graveyard") == 0){ + area = 0; + }else if(areaS.compare("library") == 0){ + area = 1; + }else if(areaS.compare("hand") == 0){ + area = 2; + }else if(areaS.compare("inplay") == 0 ){ + area = 3; + }else if(areaS.compare("life") == 0){ + playerData[playerId].life = atoi((s.substr(limiter+1)).c_str()); + return; + }else if(areaS.compare("manapool") == 0){ + SAFE_DELETE(playerData[playerId].manapool); + playerData[playerId].manapool = ManaCost::parseManaCost(s.substr(limiter+1)); + return; + }else{ + return; // ERROR + } + s = s.substr(limiter+1); + while (s.size()){ + unsigned int value; + limiter = s.find(","); + if (limiter != string::npos){ + value = atoi(s.substr(0,limiter).c_str()); + s = s.substr(limiter+1); + }else{ + value = atoi(s.c_str()); + s = ""; + } + playerData[playerId].zones[area].add(value); + } + }else{ + //ERROR + } +} + + +string TestSuite::getNextAction(){ + if (actions.nbitems && currentAction < actions.nbitems){ + currentAction++; + return actions.actions[currentAction-1]; + } + return ""; +} + + +MTGPlayerCards * TestSuite::buildDeck(MTGAllCards * collection, int playerId){ + char buf[4096]; + int list[100]; + int nbcards = 0; + for (int j = 0; j < 4; j++){ + for (int k = 0; k < initState.playerData[playerId].zones[j].nbitems; k++){ + int cardid = initState.playerData[playerId].zones[j].cards[k]; + list[nbcards] = cardid; + nbcards++; + } + } + MTGPlayerCards * deck = NEW MTGPlayerCards(collection, list, nbcards); + return deck; +} + +void TestSuite::initGame(){ + //The first test runs slowly, the other ones run faster. + //This way a human can see what happens when testing a specific file, + // or go faster when it comes to the whole test suite. + //Warning, putting this value too low (< 0.25) will give unexpected results + if (!timerLimit){ + timerLimit = 0.3; + }else{ + timerLimit = 0.26; + } + //Put the GameObserver in the initial state + GameObserver * g = GameObserver::GetInstance(); + OutputDebugString("Init Game\n"); + g->phaseRing->goToPhase(initState.phase, g->players[0]); + g->currentGamePhase = initState.phase; + for (int i = 0; i < 2; i++){ + Player * p = g->players[i]; + p->life = initState.playerData[i].life; + p->getManaPool()->copy(initState.playerData[i].manapool); + MTGGameZone * playerZones[] = {p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay}; + for (int j = 0; j < 4; j++){ + MTGGameZone * zone = playerZones[j]; + for (int k = 0; k < initState.playerData[i].zones[j].nbitems; k++){ + MTGCardInstance * card = getCardByMTGId(initState.playerData[i].zones[j].cards[k]); + if (card && zone != p->game->library){ + if (zone == p->game->inPlay){ + p->game->putInZone(card, p->game->library, p->game->hand); + Spell * spell = NEW Spell(card); + p->game->putInZone(card, p->game->hand, p->game->stack); + spell->resolve(); + card->summoningSickness = 0; + delete spell; + }else{ + if (!p->game->library->hasCard(card)){ + LOG ("ERROR, CARD NOT FOUND IN LIBRARY\n"); + } + p->game->putInZone(card,p->game->library,zone); + } + } + } + } + } + OutputDebugString("Init Game Done !\n"); +} + +int TestSuite::Log(const char * text){ + ofstream file ("Res/test/results.html",ios_base::app); + if (file){ + file << text; + file << "\n"; + file.close(); + } +#if defined (WIN32) || defined (LINUX) + OutputDebugString(text); + OutputDebugString("\n"); +#endif + return 1; + +} +int TestSuite::assertGame(){ + //compare the game state with the results + char result[4096]; + sprintf(result,"

%s

",files[currentfile-1].c_str()); + Log(result); + + int error = 0; + GameObserver * g = GameObserver::GetInstance(); + if (g->currentGamePhase != endState.phase){ + sprintf(result, "==phase problem. Expected %i, got %i==
",endState.phase, g->currentGamePhase); + Log(result); + error++; + } + for (int i = 0; i < 2; i++){ + Player * p = g->players[i]; + if (p->life != endState.playerData[i].life){ + sprintf(result, "==life problem for player %i. Expected %i, got %i==
",i,endState.playerData[i].life, p->life); + Log(result); + error++; + } + if (! p->getManaPool()->canAfford(endState.playerData[i].manapool)){ + sprintf(result, "==Mana problem. Was expecting %i but got %i for player %i==
",endState.playerData[i].manapool->getConvertedCost(),p->getManaPool()->getConvertedCost(),i); + Log(result); + error++; + } + if(! endState.playerData[i].manapool->canAfford(p->getManaPool())){ + sprintf(result, "==Mana problem. Was expecting %i but got %i for player %i==
",endState.playerData[i].manapool->getConvertedCost(),p->getManaPool()->getConvertedCost(),i); + Log(result); + error++; + + } + MTGGameZone * playerZones[] = {p->game->graveyard, p->game->library, p->game->hand, p->game->inPlay}; + for (int j = 0; j < 4; j++){ + MTGGameZone * zone = playerZones[j]; + if (zone->nb_cards != endState.playerData[i].zones[j].nbitems){ + Log("==Card number not the same==
"); + error++; + return 0; + } + for (int k = 0; k < endState.playerData[i].zones[j].nbitems; k++){ + int cardid = endState.playerData[i].zones[j].cards[k]; + int realcardid = zone->cards[k]->getMTGId(); + if ( realcardid!= cardid){ + sprintf(result, "==Card ID not the same. Expected %i, got %i==
", cardid, realcardid); + Log(result); + error++; + } + } + } + } + if (error) return 0; + Log("==Test Succesful !=="); + return 1; +} + +TestSuite::TestSuite(const char * filename){ + timerLimit = 0; + std::ifstream file(filename); + std::string s; + nbfiles = 0; + currentfile = 0; + int comment = 0; + if(file){ + while(std::getline(file,s)){ + if (s[0] == '/' && s[1] == '*') comment = 1; + if (s[0] && s[0] != '#' && !comment){ + files[nbfiles] = s; + nbfiles++; + } + if (s[0] == '*' && s[1] == '/') comment = 0; + } + file.close(); + } + + ofstream file2 ("Res/test/results.html"); + if (file2){ + file2 << ""; + file2 << ""; + file2 << "\n"; + file2.close(); + } + +} + +int TestSuite::loadNext(){ + if (!nbfiles) return 0; + if (currentfile >= nbfiles) return 0; + load(files[currentfile].c_str()); + currentfile++; + return currentfile; +} + +//TODO PArses a string and gives phase numer +int TestSuite::phaseStrToInt(string s){ + if (s.compare("untap") == 0) return MTG_PHASE_UNTAP; + if (s.compare("upkeep") == 0)return MTG_PHASE_UPKEEP; + if (s.compare("draw") == 0)return MTG_PHASE_DRAW; + if (s.compare("firstmain") == 0)return MTG_PHASE_FIRSTMAIN; + if (s.compare("combatbegin") == 0)return MTG_PHASE_COMBATBEGIN; + if (s.compare("combatattackers") == 0)return MTG_PHASE_COMBATATTACKERS; + if (s.compare("combatblockers") == 0)return MTG_PHASE_COMBATBLOCKERS; + if (s.compare("combatdamage") == 0)return MTG_PHASE_COMBATDAMAGE; + if (s.compare("combatend") == 0)return MTG_PHASE_COMBATEND; + if (s.compare("secondmain") == 0)return MTG_PHASE_SECONDMAIN; + if (s.compare("endofturn") == 0)return MTG_PHASE_ENDOFTURN; + if (s.compare("cleanup") == 0)return MTG_PHASE_CLEANUP; + return -1; +} + +void TestSuiteActions::cleanup(){ + nbitems = 0; +} + +void TestSuitePlayerZone::cleanup(){ + nbitems = 0; +} + +void TestSuitePlayerData::cleanup(){ + if (manapool) delete manapool; + manapool = NULL; + manapool = NEW ManaCost(); + for (int i = 0; i < 5; i++){ + zones[i].cleanup(); + } + life=20; +} + +void TestSuiteState::cleanup(){ + for (int i = 0; i < 2; i++){ + playerData[i].cleanup(); + } +} + +void TestSuite::cleanup(){ + currentAction = 0; + initState.cleanup(); + endState.cleanup(); + actions.cleanup(); +} + +void TestSuite::load(const char * _filename){ + char filename[4096]; + sprintf(filename, "Res/test/%s", _filename); + std::ifstream file(filename); + std::string s; + + int state = -1; + + if(file){ + cleanup(); + while(std::getline(file,s)){ + std::transform( s.begin(), s.end(), s.begin(),::tolower ); + switch(state){ + case -1: + if (s.compare("[init]") == 0) state++; + break; + case 0: + if (s.compare("[player1]") == 0){ + state++; + }else{ + initState.phase = phaseStrToInt(s); + } + break; + case 1: + if (s.compare("[player2]") == 0){ + state++; + }else{ + initState.parsePlayerState(0, s); + } + break; + case 2: + if (s.compare("[do]") == 0){ + state++; + }else{ + initState.parsePlayerState(1, s); + } + break; + case 3: + if (s.compare("[assert]") == 0){ + state++; + }else{ + actions.add(s); + } + break; + case 4: + if (s.compare("[player1]") == 0){ + state++; + }else{ + endState.phase = phaseStrToInt(s); + } + break; + case 5: + if (s.compare("[player2]") == 0){ + state++; + }else{ + endState.parsePlayerState(0, s); + } + break; + case 6: + if (s.compare("[end]") == 0){ + state++; + }else{ + endState.parsePlayerState(1, s); + } + break; + } + } + file.close(); + }else{ + //TODO Error management + } +} + diff --git a/projects/mtg/src/TexturesCache.cpp b/projects/mtg/src/TexturesCache.cpp index 17ef0d3ec..db36dbaf3 100644 --- a/projects/mtg/src/TexturesCache.cpp +++ b/projects/mtg/src/TexturesCache.cpp @@ -3,27 +3,27 @@ TexturesCache::TexturesCache(){ nb_textures = 0; - totalsize = 0; + totalsize = 0; delete_previous = 0; - lastTime = 0; - for (int i=0; igetId(), type); - if (cache_id == -1) - return 0; - return 1; + int cache_id = getCacheById(card->getId(), type); + if (cache_id == -1) + return 0; + return 1; } int TexturesCache::getCacheById(int id, int type){ @@ -37,32 +37,32 @@ int TexturesCache::getCacheById(int id, int type){ } int TexturesCache::getOldestQuad(){ - int oldest = -1; - int result = -1; - for (int i= 0; i < nb_textures; i++){ - if (oldest == -1 || oldest > cache[i]->lastTime){ - oldest = cache[i]->lastTime; - result = i; - } - } - return result; + int oldest = -1; + int result = -1; + for (int i= 0; i < nb_textures; i++){ + if (oldest == -1 || oldest > cache[i]->lastTime){ + oldest = cache[i]->lastTime; + result = i; + } + } + return result; } void TexturesCache::removeQuad(int id){ - totalsize -= cache[id]->nbpixels; - delete cache[id]; - cache[id] = cache[nb_textures - 1]; - cache[nb_textures - 1] = NULL; - nb_textures--; + totalsize -= cache[id]->nbpixels; + delete cache[id]; + cache[id] = cache[nb_textures - 1]; + cache[nb_textures - 1] = NULL; + nb_textures--; } int TexturesCache::cleanup(){ - while (nb_textures >= MAX_CACHE_OBJECTS - 1 || totalsize > CACHE_SIZE_PIXELS){ - int i = getOldestQuad(); - if (i == -1) return 0; - removeQuad(i); - } - return 1; + while (nb_textures >= MAX_CACHE_OBJECTS - 1 || totalsize > CACHE_SIZE_PIXELS){ + int i = getOldestQuad(); + if (i == -1) return 0; + removeQuad(i); + } + return 1; } JQuad * TexturesCache::getQuad(MTGCard * card, int type){ @@ -70,14 +70,14 @@ JQuad * TexturesCache::getQuad(MTGCard * card, int type){ if (cache_id == -1){ fprintf(stderr, "not found %d\n", card->getId()); //Not found in the cache, we have to load the file and put it in the cache - if (cleanup()){ - cache_id = nb_textures; - cache[cache_id] = NEW CardTexture(card, type); - totalsize+= cache[cache_id]->nbpixels; - nb_textures++; - } + if (cleanup()){ + cache_id = nb_textures; + cache[cache_id] = NEW CardTexture(card, type); + totalsize+= cache[cache_id]->nbpixels; + nb_textures++; + } } - cache[cache_id]->lastTime = lastTime++; + cache[cache_id]->lastTime = lastTime++; return cache[cache_id]->getQuad(); } @@ -86,24 +86,24 @@ int CardTexture::getId(){ } CardTexture::CardTexture(MTGCard * card, int _type): type(_type){ - LOG("==Creating CardTexture Object"); + LOG("==Creating CardTexture Object"); char filename[100]; quad = NULL; - nbpixels = 0; - lastTime = 0; - if (type == CACHE_THUMB){ - sprintf(filename, "sets/%s/thumbnails/%s", card->getSetName(), card->getImageName()); - }else{ - sprintf(filename, "sets/%s/%s", card->getSetName(), card->getImageName()); - } + nbpixels = 0; + lastTime = 0; + if (type == CACHE_THUMB){ + sprintf(filename, "sets/%s/thumbnails/%s", card->getSetName(), card->getImageName()); + }else{ + sprintf(filename, "sets/%s/%s", card->getSetName(), card->getImageName()); + } tex = JRenderer::GetInstance()->LoadTexture(filename, false); if (tex){ - quad = NEW JQuad(tex, 0.0f, 0.0f, tex->mWidth, tex->mHeight); - nbpixels = tex->mTexHeight * tex->mTexWidth; + quad = NEW JQuad(tex, 0.0f, 0.0f, tex->mWidth, tex->mHeight); + nbpixels = tex->mTexHeight * tex->mTexWidth; } mtgid = card->getId(); - LOG("CardTexture Object Creation succesful"); + LOG("CardTexture Object Creation succesful"); } JQuad * CardTexture::getQuad(){ @@ -111,9 +111,9 @@ JQuad * CardTexture::getQuad(){ } CardTexture::~CardTexture(){ - LOG("==Deleting CardTexture Object"); + LOG("==Deleting CardTexture Object"); SAFE_DELETE(quad); SAFE_DELETE(tex); - LOG("CardTexture Object deletion Succesful"); + LOG("CardTexture Object deletion Succesful"); } diff --git a/projects/mtg/src/utils.cpp b/projects/mtg/src/utils.cpp index 82f18b84c..a80e6b122 100644 --- a/projects/mtg/src/utils.cpp +++ b/projects/mtg/src/utils.cpp @@ -1,144 +1,144 @@ -#include "../include/debug.h" -#include "../include/utils.h" - - -int lowercase(string sBuffer) { -std::transform( sBuffer.begin(), sBuffer.end(), sBuffer.begin(), -::tolower ); - return 1; -} - - -int substr_copy(char *source, char *target, int start, int len){ - int i=0; - int not_over = 1; - while (not_over){ - if (source[i+start] == 0 || i == len-1){ - not_over = 0; - } - target[i] = source[i + start]; - i++; - if (i == len){ - target[i] = 0; - } - } - return i; -} - - -int append_str(char * s1, char * s2, char * target){ - int len = substr_copy(s1,target, 0,0); - substr_copy(s2,target+len-1,0,0); - return 0; -} - - - -int filesize(const char * filename){ - int file_size = 0; - #if defined (WIN32) || defined (LINUX) - FILE * file = fopen(filename, "rb"); - if (file != NULL) - { - fseek(file, 0, SEEK_END); - file_size = ftell(file); - fclose(file); - } - - #else - int file = sceIoOpen(filename,PSP_O_RDONLY, 0777); - if (file > 0){ - file_size = sceIoLseek(file, 0, PSP_SEEK_END); - sceIoClose(file); - } - - #endif - return file_size; -} - -int read_file (const char * filename, char * buffer, int file_size){ - int a = 0; -#if defined (WIN32) || defined (LINUX) - FILE * file = fopen(filename, "rb"); - a = fread(buffer, 1, file_size, file); - fclose(file); -#else - int file = sceIoOpen(filename,PSP_O_RDONLY, 0777); - - a = sceIoRead(file, buffer, file_size); - sceIoClose(file); -#endif - - fprintf(stderr, "The first string in the file is %d characters long.\n", strlen(&buffer[0]) ); - return a; - -} - -int readline (char * in_buffer, char * out_buffer, int cursor){ - char a; - int found = 0; - int i = 0; - - //int read_ok = 0; - while (found == 0){ - a = in_buffer[cursor]; - cursor++; - if (a == '\r'){ - a = in_buffer[cursor]; - cursor ++; - } - if (a == 0){ - found = 1; - cursor = 0; - }else{ - if(a == '\n' || i==(BUFSIZE - 1)){ - found = 1; - out_buffer[i] = 0; - - if (a != '\n'){ - int endofline = 0; - while (!endofline){ - //int read; - a = in_buffer[cursor]; - - cursor++; - if (a == 0 || a=='\n'){ - endofline = 1; - fprintf(stderr, "buffer overflow in readline %s\n", out_buffer); - } - if (a == 0 ){ - cursor = 0; - } - } - } - }else{ - out_buffer[i] = a; - i++; - } - - } - } - out_buffer[i] = 0; - return(cursor); - } - - - -int readfile_to_ints(const char * filename, int * out_buffer){ - std::ifstream fichier(filename); - std::string s; - unsigned int count = 0; -if(fichier){ - while(std::getline(fichier,s)){ - int value = atoi(s.c_str()); - if (value){ - out_buffer[count] = value; - ++count; - } - } - -} -fichier.close(); -return count; - -} +#include "../include/debug.h" +#include "../include/utils.h" + + +int lowercase(string sBuffer) { + std::transform( sBuffer.begin(), sBuffer.end(), sBuffer.begin(), + ::tolower ); + return 1; +} + + +int substr_copy(char *source, char *target, int start, int len){ + int i=0; + int not_over = 1; + while (not_over){ + if (source[i+start] == 0 || i == len-1){ + not_over = 0; + } + target[i] = source[i + start]; + i++; + if (i == len){ + target[i] = 0; + } + } + return i; +} + + +int append_str(char * s1, char * s2, char * target){ + int len = substr_copy(s1,target, 0,0); + substr_copy(s2,target+len-1,0,0); + return 0; +} + + + +int filesize(const char * filename){ + int file_size = 0; +#if defined (WIN32) || defined (LINUX) + FILE * file = fopen(filename, "rb"); + if (file != NULL) + { + fseek(file, 0, SEEK_END); + file_size = ftell(file); + fclose(file); + } + +#else + int file = sceIoOpen(filename,PSP_O_RDONLY, 0777); + if (file > 0){ + file_size = sceIoLseek(file, 0, PSP_SEEK_END); + sceIoClose(file); + } + +#endif + return file_size; +} + +int read_file (const char * filename, char * buffer, int file_size){ + int a = 0; +#if defined (WIN32) || defined (LINUX) + FILE * file = fopen(filename, "rb"); + a = fread(buffer, 1, file_size, file); + fclose(file); +#else + int file = sceIoOpen(filename,PSP_O_RDONLY, 0777); + + a = sceIoRead(file, buffer, file_size); + sceIoClose(file); +#endif + + fprintf(stderr, "The first string in the file is %d characters long.\n", strlen(&buffer[0]) ); + return a; + +} + +int readline (char * in_buffer, char * out_buffer, int cursor){ + char a; + int found = 0; + int i = 0; + + //int read_ok = 0; + while (found == 0){ + a = in_buffer[cursor]; + cursor++; + if (a == '\r'){ + a = in_buffer[cursor]; + cursor ++; + } + if (a == 0){ + found = 1; + cursor = 0; + }else{ + if(a == '\n' || i==(BUFSIZE - 1)){ + found = 1; + out_buffer[i] = 0; + + if (a != '\n'){ + int endofline = 0; + while (!endofline){ + //int read; + a = in_buffer[cursor]; + + cursor++; + if (a == 0 || a=='\n'){ + endofline = 1; + fprintf(stderr, "buffer overflow in readline %s\n", out_buffer); + } + if (a == 0 ){ + cursor = 0; + } + } + } + }else{ + out_buffer[i] = a; + i++; + } + + } + } + out_buffer[i] = 0; + return(cursor); +} + + + +int readfile_to_ints(const char * filename, int * out_buffer){ + std::ifstream fichier(filename); + std::string s; + unsigned int count = 0; + if(fichier){ + while(std::getline(fichier,s)){ + int value = atoi(s.c_str()); + if (value){ + out_buffer[count] = value; + ++count; + } + } + + } + fichier.close(); + return count; + +}