- Updated Parser mechanism. Right now this doesn't change functionalities much, but should be more readable, and make it easier to code some new abilities in the future
- Fixed regenerate, broken with r532
- Death Ward now works
- I think "&&" now works with all abilities, needs to be tested...
This commit is contained in:
wagic.the.homebrew@gmail.com
2009-07-11 15:59:51 +00:00
parent 307c41c563
commit c8333e76b1
34 changed files with 2157 additions and 1816 deletions

View File

@@ -501,6 +501,7 @@ mana={W}
text={B}{B}: Counter target green spell. text={B}{B}: Counter target green spell.
id=1151 id=1151
name=Deathgrip name=Deathgrip
auto={B}{B}:fizzle target(*[green]|stack)
rarity=U rarity=U
type=Enchantment type=Enchantment
mana={B}{B} mana={B}{B}
@@ -1251,6 +1252,7 @@ toughness=1
text={G}{G}: Counter target black spell. text={G}{G}: Counter target black spell.
id=1256 id=1256
name=Lifeforce name=Lifeforce
auto={G}{G}:fizzle target(*[black]|stack)
rarity=U rarity=U
type=Enchantment type=Enchantment
mana={G}{G} mana={G}{G}

View File

@@ -13,6 +13,8 @@ generic/legendary.txt
generic/lifelink.txt generic/lifelink.txt
generic/persist.txt generic/persist.txt
generic/persist2.txt generic/persist2.txt
generic/rampage.txt
generic/regenerate.txt
generic/sacrifice.txt generic/sacrifice.txt
generic/wither.txt generic/wither.txt
######################## ########################
@@ -22,6 +24,7 @@ afflict.txt
akron_legionnaire.txt akron_legionnaire.txt
Amugaba.txt Amugaba.txt
anarchy.txt anarchy.txt
ancestors_chosen.txt
animate_dead.txt animate_dead.txt
animate_dead2.txt animate_dead2.txt
animate_dead3.txt animate_dead3.txt
@@ -57,6 +60,7 @@ counterspell3.txt
counterspell4.txt counterspell4.txt
creature_bond.txt creature_bond.txt
dauthi_embrace.txt dauthi_embrace.txt
death_ward.txt
deja_vu.txt deja_vu.txt
dingus_egg.txt dingus_egg.txt
doomed_necromancer.txt doomed_necromancer.txt
@@ -76,12 +80,14 @@ fountain_of_youth.txt
ghost_warden.txt ghost_warden.txt
giant_growth.txt giant_growth.txt
giant_growth2.txt giant_growth2.txt
glimpse_the_unthinkable.txt
goblin_balloon_brigade.txt goblin_balloon_brigade.txt
goblin_balloon_brigade2.txt goblin_balloon_brigade2.txt
goblin_king.txt goblin_king.txt
gravedigger.txt gravedigger.txt
#hammerfist_giant.txt #hammerfist_giant.txt
hannas_custody.txt hannas_custody.txt
howl_of_the_night_pack.txt
hymn_of_rebirth.txt hymn_of_rebirth.txt
icatian_priest.txt icatian_priest.txt
keldon_warlord.txt keldon_warlord.txt
@@ -95,6 +101,8 @@ living_lands.txt
lord_of_the_pit.txt lord_of_the_pit.txt
lord_of_the_pit2.txt lord_of_the_pit2.txt
master_of_etherium.txt master_of_etherium.txt
millstone.txt
mind_rot.txt
nantuko_husk.txt nantuko_husk.txt
Nevinyrrals_Disk.txt Nevinyrrals_Disk.txt
Nevinyrrals_Disk2.txt Nevinyrrals_Disk2.txt
@@ -118,8 +126,10 @@ siege_gang_commander.txt
shivan_hellkite.txt shivan_hellkite.txt
shock.txt shock.txt
sphinx_summoner.txt sphinx_summoner.txt
spitting_earth.txt
spark_elemental.txt spark_elemental.txt
spirit_link.txt spirit_link.txt
spoils_of_evil.txt
stasis.txt stasis.txt
steelclad_serpent1.txt steelclad_serpent1.txt
steelclad_serpent2.txt steelclad_serpent2.txt

View File

@@ -0,0 +1,21 @@
#Testing Ancestors chosen
[INIT]
FIRSTMAIN
[PLAYER1]
hand:Ancestor's chosen
graveyard:swamp,grizzly bears,dragon engine
manapool:{5}{W}{W}
[PLAYER2]
graveyard:black knight
[DO]
Ancestor's chosen
[ASSERT]
FIRSTMAIN
[PLAYER1]
inplay:Ancestor's chosen
life:23
graveyard:swamp,grizzly bears,dragon engine
manapool:{0}
[PLAYER2]
graveyard:black knight
[END]

View File

@@ -0,0 +1,26 @@
#Testing Regenerate (Death Ward)
[INIT]
COMBATATTACKERS
[PLAYER1]
hand:Death Ward
manapool:{W}
inplay:raging goblin
[PLAYER2]
inplay:grizzly bears
[DO]
Death Ward
raging goblin
raging goblin
next
grizzly bears
next
next
[ASSERT]
COMBATEND
[PLAYER1]
inplay:raging goblin
graveyard:Death Ward
manapool:{0}
[PLAYER2]
inplay:grizzly bears
[END]

View File

@@ -0,0 +1,20 @@
#Testing Rampage
[INIT]
COMBATATTACKERS
[PLAYER1]
inplay:Elvish Berserker
[PLAYER2]
inplay:raging goblin
[DO]
Elvish Berserker
next
raging goblin
next
next
[ASSERT]
COMBATEND
[PLAYER1]
inplay:Elvish Berserker
[PLAYER2]
graveyard:raging goblin
[END]

View File

@@ -0,0 +1,22 @@
#Testing Regenerate
[INIT]
COMBATATTACKERS
[PLAYER1]
inplay:Drudge Skeletons,swamp
[PLAYER2]
inplay:raging goblin
[DO]
Drudge skeletons
swamp
Drudge skeletons
next
raging goblin
next
next
[ASSERT]
COMBATEND
[PLAYER1]
inplay:Drudge Skeletons,swamp
[PLAYER2]
graveyard:raging goblin
[END]

View File

@@ -0,0 +1,20 @@
#Testing Deplete (sorcery
[INIT]
FIRSTMAIN
[PLAYER1]
hand:Glimpse the Unthinkable
manapool:{U}{B}
[PLAYER2]
library:swamp,plains,mountain,forest,island,bayou,plateau,white knight,black knight,grizzly bears,raging goblin
[DO]
Glimpse the Unthinkable
p2
[ASSERT]
FIRSTMAIN
[PLAYER1]
graveyard:Glimpse the Unthinkable
manapool:{0}
[PLAYER2]
library:swamp
graveyard:plains,mountain,forest,island,bayou,plateau,white knight,black knight,grizzly bears,raging goblin
[END]

View File

@@ -0,0 +1,18 @@
#Testing Howl of the night pack
[INIT]
FIRSTMAIN
[PLAYER1]
hand:153996
inplay:1386,1387,1388
manapool:{6}{G}
[PLAYER2]
[DO]
153996
[ASSERT]
FIRSTMAIN
[PLAYER1]
inplay:1386,1387,1388,*,*,*
graveyard:153996
manapool:{0}
[PLAYER2]
[END]

View File

@@ -0,0 +1,20 @@
#Testing Deplete
[INIT]
FIRSTMAIN
[PLAYER1]
inplay:Millstone
manapool:{2}}
[PLAYER2]
library:swamp,plains,mountain,forest,island,bayou,plateau,white knight,black knight,grizzly bears,raging goblin
[DO]
Millstone
p2
[ASSERT]
FIRSTMAIN
[PLAYER1]
inplay:Millstone
manapool:{0}
[PLAYER2]
library:swamp,plains,mountain,forest,island,bayou,plateau,white knight,black knight
graveyard:grizzly bears,raging goblin
[END]

View File

@@ -0,0 +1,20 @@
#Testing Random discard
[INIT]
FIRSTMAIN
[PLAYER1]
hand:Mind Rot
manapool:{2}{B}
[PLAYER2]
hand:swamp,plains,mountain
[DO]
Mind Rot
p2
[ASSERT]
FIRSTMAIN
[PLAYER1]
graveyard:Mind Rot
manapool:{0}
[PLAYER2]
hand:*
graveyard:*,*
[END]

View File

@@ -0,0 +1,22 @@
#Testing Spitting Earth on Dragon engine
[INIT]
FIRSTMAIN
[PLAYER1]
hand:Spitting Earth
inplay:129652,129651,129650
[PLAYER2]
inplay:Dragon Engine
[DO]
129652
129651
Spitting Earth
Dragon Engine
[ASSERT]
FIRSTMAIN
[PLAYER1]
inplay:129652,129651,129650
graveyard:Spitting Earth
manapool:{0}
[PLAYER2]
graveyard:Dragon Engine
[END]

View File

@@ -0,0 +1,20 @@
#Testing Spoils of Evil
[INIT]
FIRSTMAIN
[PLAYER1]
hand:Spoils Of Evil
graveyard:black knight
manapool:{2}{B}
[PLAYER2]
graveyard:swamp,grizzly bears,dragon engine
[DO]
Spoils Of Evil
[ASSERT]
FIRSTMAIN
[PLAYER1]
graveyard:black knight,Spoils Of Evil
life:22
manapool:{2}
[PLAYER2]
graveyard:swamp,grizzly bears,dragon engine
[END]

View File

@@ -22,10 +22,11 @@ class WEvent;
class ActionElement: public JGuiObject{ class ActionElement: public JGuiObject{
protected: protected:
int activeState; int activeState;
public: public:
int isClone;
TargetChooser * tc; TargetChooser * tc;
int currentPhase; int currentPhase;
int newPhase; int newPhase;
@@ -46,6 +47,7 @@ class ActionElement: public JGuiObject{
virtual int receiveEvent(WEvent * event){return 0;}; virtual int receiveEvent(WEvent * event){return 0;};
virtual int reactToClick(MTGCardInstance * card){return 0;}; virtual int reactToClick(MTGCardInstance * card){return 0;};
virtual const char * getMenuText(){return "Ability";}; virtual const char * getMenuText(){return "Ability";};
virtual ActionElement * clone() const = 0;
}; };

File diff suppressed because it is too large Load Diff

View File

@@ -27,6 +27,7 @@ class UntapBlocker : public MTGAbility {
~UntapBlocker(); ~UntapBlocker();
virtual void Update(float dt); virtual void Update(float dt);
virtual int destroy(); virtual int destroy();
virtual UntapBlocker * clone() const;
}; };

View File

@@ -25,7 +25,7 @@ class GuiLayer{
int mCurr; int mCurr;
vector<JGuiObject *>mObjects; vector<JGuiObject *>mObjects;
void Add(JGuiObject * object); void Add(JGuiObject * object);
void Remove(JGuiObject * object); int Remove(JGuiObject * object);
int modal; int modal;
bool hasFocus; bool hasFocus;
virtual void resetObjects(); virtual void resetObjects();

View File

@@ -19,15 +19,18 @@ class WEvent;
#include <string> #include <string>
#include <map> #include <map>
#include <hge/hgeparticle.h> #include <hge/hgeparticle.h>
#include "../include/Damage.h"
using std::string; using std::string;
using std::map; using std::map;
//Two stupid variables used to give a hint to the AI: //stupid variables used to give a hint to the AI:
// Should I cast a spell on an enemy or friendly unit ? // Should I cast a spell on an enemy or friendly unit ?
#define BAKA_EFFECT_GOOD 1 #define BAKA_EFFECT_GOOD 1
#define BAKA_EFFECT_BAD -1 #define BAKA_EFFECT_BAD -1
#define BAKA_EFFECT_DONTKNOW 0 #define BAKA_EFFECT_DONTKNOW 0
#define MODE_PUTINTOPLAY 1
#define MODE_ABILITY 2
#define COUNT_POWER 1 #define COUNT_POWER 1
@@ -38,16 +41,17 @@ using std::map;
class MTGAbility: public ActionElement{ class MTGAbility: public ActionElement{
protected: protected:
char menuText[25]; char menuText[25];
GameObserver * game; GameObserver * game;
public: public:
int oneShot;
int forceDestroy; int forceDestroy;
ManaCost * cost; ManaCost * cost;
Damageable * target; Targetable * target;
int aType; int aType;
MTGCardInstance * source; MTGCardInstance * source;
MTGAbility(int id, MTGCardInstance * card); MTGAbility(int id, MTGCardInstance * card);
MTGAbility(int id, MTGCardInstance * _source, Damageable * _target); MTGAbility(int id, MTGCardInstance * _source, Targetable * _target);
virtual int testDestroy(); virtual int testDestroy();
virtual ~MTGAbility(); virtual ~MTGAbility();
virtual void Render(){}; virtual void Render(){};
@@ -58,7 +62,10 @@ class MTGAbility: public ActionElement{
virtual int fireAbility(); virtual int fireAbility();
virtual int stillInUse(MTGCardInstance * card){if (card==source) return 1; return 0;}; virtual int stillInUse(MTGCardInstance * card){if (card==source) return 1; return 0;};
virtual int resolve(){return 0;}; virtual int resolve(){return 0;};
virtual MTGAbility* clone() const = 0;
virtual ostream& toString(ostream& out) const; virtual ostream& toString(ostream& out) const;
virtual int addToGame();
virtual int removeFromGame();
/*Poor man's casting */ /*Poor man's casting */
/* Todo replace that crap with dynamic casting */ /* Todo replace that crap with dynamic casting */
@@ -78,11 +85,12 @@ class MTGAbility: public ActionElement{
class TriggeredAbility:public MTGAbility{ class TriggeredAbility:public MTGAbility{
public: public:
TriggeredAbility(int id, MTGCardInstance * card); TriggeredAbility(int id, MTGCardInstance * card);
TriggeredAbility(int id, MTGCardInstance * _source, Damageable * _target); TriggeredAbility(int id, MTGCardInstance * _source, Targetable * _target);
virtual void Update(float dt); virtual void Update(float dt);
virtual void Render(){}; virtual void Render(){};
virtual int trigger()=0; virtual int trigger()=0;
virtual int resolve() = 0; virtual int resolve() = 0;
virtual TriggeredAbility* clone() const = 0;
virtual ostream& toString(ostream& out) const; virtual ostream& toString(ostream& out) const;
}; };
@@ -96,18 +104,24 @@ class ActivatedAbility:public MTGAbility{
virtual int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL); virtual int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
virtual int reactToTargetClick(Targetable * object); virtual int reactToTargetClick(Targetable * object);
virtual int resolve() = 0; virtual int resolve() = 0;
virtual ActivatedAbility* clone() const = 0;
virtual ostream& toString(ostream& out) const; virtual ostream& toString(ostream& out) const;
}; };
class TargetAbility:public ActivatedAbility{ class TargetAbility:public ActivatedAbility{
public: public:
MTGAbility * ability;
TargetAbility(int id, MTGCardInstance * card, TargetChooser * _tc,ManaCost * _cost = NULL, int _playerturnonly = 0,int tap = 1); 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); TargetAbility(int id, MTGCardInstance * card,ManaCost * _cost = NULL, int _playerturnonly = 0,int tap = 1);
virtual void Update(float dt); virtual void Update(float dt);
virtual int reactToClick(MTGCardInstance * card); virtual int reactToClick(MTGCardInstance * card);
virtual int reactToTargetClick(Targetable * object); virtual int reactToTargetClick(Targetable * object);
virtual TargetAbility* clone() const = 0;
virtual void Render(); virtual void Render();
virtual int resolve();
virtual const char * getMenuText();
virtual ostream& toString(ostream& out) const; virtual ostream& toString(ostream& out) const;
~TargetAbility();
}; };
class InstantAbility:public MTGAbility{ class InstantAbility:public MTGAbility{
@@ -118,6 +132,7 @@ class InstantAbility:public MTGAbility{
InstantAbility(int _id, MTGCardInstance * source); InstantAbility(int _id, MTGCardInstance * source);
InstantAbility(int _id, MTGCardInstance * source,Damageable * _target); InstantAbility(int _id, MTGCardInstance * source,Damageable * _target);
virtual int resolve(){return 0;}; virtual int resolve(){return 0;};
virtual InstantAbility* clone() const = 0;
virtual ostream& toString(ostream& out) const; virtual ostream& toString(ostream& out) const;
}; };
@@ -125,26 +140,32 @@ class InstantAbility:public MTGAbility{
class ListMaintainerAbility:public MTGAbility{ class ListMaintainerAbility:public MTGAbility{
public: public:
map<MTGCardInstance *,bool> cards; map<MTGCardInstance *,bool> cards;
map<Player *,bool> players;
ListMaintainerAbility(int _id):MTGAbility(_id,NULL){}; ListMaintainerAbility(int _id):MTGAbility(_id,NULL){};
ListMaintainerAbility(int _id, MTGCardInstance *_source):MTGAbility(_id, _source){}; ListMaintainerAbility(int _id, MTGCardInstance *_source):MTGAbility(_id, _source){};
ListMaintainerAbility(int _id, MTGCardInstance *_source,Damageable * _target):MTGAbility(_id, _source, _target){}; ListMaintainerAbility(int _id, MTGCardInstance *_source,Damageable * _target):MTGAbility(_id, _source, _target){};
virtual void Update(float dt); virtual void Update(float dt);
void updateTargets();
virtual int canBeInList(MTGCardInstance * card) = 0; virtual int canBeInList(MTGCardInstance * card) = 0;
virtual int added(MTGCardInstance * card) = 0; virtual int added(MTGCardInstance * card) = 0;
virtual int removed(MTGCardInstance * card) = 0; virtual int removed(MTGCardInstance * card) = 0;
virtual int canBeInList(Player * p){return 0;};
virtual int added(Player * p){return 0;};
virtual int removed(Player * p){return 0;};
virtual int destroy(); virtual int destroy();
virtual ListMaintainerAbility* clone() const = 0;
virtual ostream& toString(ostream& out) const; virtual ostream& toString(ostream& out) const;
}; };
/* An attempt to globalize triggered abilities as much as possible */ /* An attempt to globalize triggered abilities as much as possible */
class MTGAbilityBasicFeatures{ class MTGAbilityBasicFeatures{
public: public:
Damageable * target; Targetable * target;
GameObserver * game; GameObserver * game;
MTGCardInstance * source; MTGCardInstance * source;
MTGAbilityBasicFeatures(); MTGAbilityBasicFeatures();
MTGAbilityBasicFeatures(MTGCardInstance * _source, Damageable * _target = NULL); MTGAbilityBasicFeatures(MTGCardInstance * _source, Targetable * _target = NULL);
void init(MTGCardInstance * _source, Damageable * _target = NULL); void init(MTGCardInstance * _source, Targetable * _target = NULL);
}; };
class Trigger:public MTGAbilityBasicFeatures{ class Trigger:public MTGAbilityBasicFeatures{
@@ -176,7 +197,7 @@ class TriggerNextPhase:public TriggerAtPhase{
class TriggeredEvent:public MTGAbilityBasicFeatures{ class TriggeredEvent:public MTGAbilityBasicFeatures{
public: public:
TriggeredEvent(); TriggeredEvent();
TriggeredEvent(MTGCardInstance * source, Damageable * target = NULL); TriggeredEvent(MTGCardInstance * source, Targetable * target = NULL);
virtual int resolve()=0; virtual int resolve()=0;
}; };
@@ -213,21 +234,22 @@ class GenericTriggeredAbility:public TriggeredAbility{
Trigger * t; Trigger * t;
TriggeredEvent * te; TriggeredEvent * te;
DestroyCondition * dc; DestroyCondition * dc;
GenericTriggeredAbility(int id, MTGCardInstance * _source, Trigger * _t, TriggeredEvent * _te, DestroyCondition * _dc = NULL, Damageable * _target = NULL); GenericTriggeredAbility(int id, MTGCardInstance * _source, Trigger * _t, TriggeredEvent * _te, DestroyCondition * _dc = NULL, Targetable * _target = NULL);
virtual int trigger(); virtual int trigger();
virtual int resolve(); virtual int resolve();
virtual int testDestroy(); virtual int testDestroy();
virtual GenericTriggeredAbility* clone() const;
~GenericTriggeredAbility(); ~GenericTriggeredAbility();
}; };
/* Ability Factory */ /* Ability Factory */
class AbilityFactory{ class AbilityFactory{
private: private:
int countCards(TargetChooser * tc, Player * player = NULL, int option = 0); int countCards(TargetChooser * tc, Player * player = NULL, int option = 0);
int putInPlayFromZone(MTGCardInstance * card, MTGGameZone * zone, Player * p);
int parsePowerToughness(string s, int *power, int *toughness); int parsePowerToughness(string s, int *power, int *toughness);
Trigger * parseTrigger(string magicText); Trigger * parseTrigger(string magicText);
Damageable * parseCollateralTarget(MTGCardInstance * card, string s); MTGAbility * parseMagicLine(string s, int id, Spell * spell, MTGCardInstance *card, int activated = 0);
int abilityEfficiency(MTGAbility * a, Player * p, int mode = MODE_ABILITY);
public: public:
int magicText(int id, Spell * spell, MTGCardInstance * card = NULL); int magicText(int id, Spell * spell, MTGCardInstance * card = NULL);
int destroyAllInPlay(TargetChooser * tc, int bury = 0); int destroyAllInPlay(TargetChooser * tc, int bury = 0);
@@ -243,16 +265,16 @@ class AbilityFactory{
class AManaProducer: public MTGAbility{ class AManaProducer: public MTGAbility{
protected: protected:
ManaCost * cost;
ManaCost * output; ManaCost * output;
string menutext; string menutext;
float x0,y0,x1,y1,x,y; float x0,y0,x1,y1,x,y;
float animation; float animation;
Player * controller; Player * controller;
int tap;
hgeParticleSystem * mParticleSys; hgeParticleSystem * mParticleSys;
public: public:
int tap;
static int currentlyTapping; static int currentlyTapping;
AManaProducer(int id, MTGCardInstance * card, ManaCost * _output, ManaCost * _cost = NULL, int doTap = 1 ); AManaProducer(int id, MTGCardInstance * card, ManaCost * _output, ManaCost * _cost = NULL, int doTap = 1 );
void Update(float dt); void Update(float dt);
@@ -263,6 +285,7 @@ class AManaProducer: public MTGAbility{
const char * getMenuText(); const char * getMenuText();
int testDestroy(); int testDestroy();
~AManaProducer(); ~AManaProducer();
virtual AManaProducer * clone() const;
virtual ostream& toString(ostream& out) const; virtual ostream& toString(ostream& out) const;
}; };

View File

@@ -18,6 +18,7 @@ class MTGGamePhase: public ActionElement {
virtual void Render(); virtual void Render();
virtual void Update(float dt); virtual void Update(float dt);
bool CheckUserInput(u32 key); bool CheckUserInput(u32 key);
virtual MTGGamePhase * clone() const;
virtual ostream& toString(ostream& out) const; virtual ostream& toString(ostream& out) const;
}; };

View File

@@ -16,6 +16,7 @@ class MTGPutInPlayRule:public MTGAbility{
virtual ostream& toString(ostream& out) const; virtual ostream& toString(ostream& out) const;
MTGPutInPlayRule(int _id); MTGPutInPlayRule(int _id);
const char * getMenuText(){return "Put into play";} const char * getMenuText(){return "Put into play";}
virtual MTGPutInPlayRule * clone() const;
}; };
class MTGAttackRule:public MTGAbility{ class MTGAttackRule:public MTGAbility{
@@ -27,6 +28,7 @@ class MTGAttackRule:public MTGAbility{
MTGAttackRule(int _id); MTGAttackRule(int _id);
const char * getMenuText(){return "Attacker";} const char * getMenuText(){return "Attacker";}
void Update(float dt); void Update(float dt);
virtual MTGAttackRule * clone() const;
}; };
class MTGBlockRule:public MTGAbility{ class MTGBlockRule:public MTGAbility{
@@ -37,49 +39,18 @@ class MTGBlockRule:public MTGAbility{
virtual ostream& toString(ostream& out) const; virtual ostream& toString(ostream& out) const;
MTGBlockRule(int _id); MTGBlockRule(int _id);
const char * getMenuText(){return "Blocker";} const char * getMenuText(){return "Blocker";}
virtual MTGBlockRule * clone() const;
}; };
/* Persist Rule */ /* Persist Rule */
class MTGPersistRule:public MTGAbility{ class MTGPersistRule:public MTGAbility{
public: public:
MTGPersistRule(int _id):MTGAbility(_id,NULL){}; MTGPersistRule(int _id);
int receiveEvent(WEvent * event);
int receiveEvent(WEvent * event){ virtual ostream& toString(ostream& out) const;
if (event->type == WEvent::CHANGE_ZONE){ int testDestroy();
WEventZoneChange * e = (WEventZoneChange *) event; virtual MTGPersistRule * clone() const;
MTGCardInstance * card = e->card->previous;
if (card && card->basicAbilities[Constants::PERSIST] && !card->counters->hasCounter(-1,-1)){
int ok = 0;
for (int i = 0; i < 2 ; i++){
Player * p = game->players[i];
if (e->from == p->game->inPlay) ok = 1;
}
if (!ok) return 0;
for (int i = 0; i < 2 ; i++){
Player * p = game->players[i];
if (e->to == p->game->graveyard){
//p->game->putInZone(card, p->game->graveyard, card->owner->game->hand);
MTGCardInstance * copy = p->game->putInZone(e->card, p->game->graveyard, e->card->owner->game->stack);
Spell * spell = NEW Spell(copy);
spell->resolve();
spell->source->counters->addCounter(-1,-1);
game->mLayers->playLayer()->forceUpdateCards();
delete spell;
return 1;
}
}
}
}
return 0;
}
virtual ostream& toString(ostream& out) const
{
out << "MTGPersistRule ::: (";
return MTGAbility::toString(out) << ")";
}
int testDestroy(){return 0;}
}; };
@@ -91,39 +62,13 @@ class MTGPersistRule:public MTGAbility{
*/ */
class MTGLegendRule:public ListMaintainerAbility{ class MTGLegendRule:public ListMaintainerAbility{
public: public:
MTGLegendRule(int _id):ListMaintainerAbility(_id){}; MTGLegendRule(int _id);
int canBeInList(MTGCardInstance * card);
int canBeInList(MTGCardInstance * card){ int added(MTGCardInstance * card);
if (card->basicAbilities[Constants::LEGENDARY] && game->isInPlay(card)){ int removed(MTGCardInstance * card);
return 1; int testDestroy();
} virtual ostream& toString(ostream& out) const;
return 0; virtual MTGLegendRule * clone() const;
}
int added(MTGCardInstance * card){
map<MTGCardInstance *,bool>::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;}
virtual ostream& toString(ostream& out) const
{
return out << "MTGLegendRule :::";
}
}; };
@@ -149,34 +94,22 @@ public:
int reactToClick(MTGCardInstance * card, int id); int reactToClick(MTGCardInstance * card, int id);
const char * getMenuText(){return "Momir";} const char * getMenuText(){return "Momir";}
virtual ostream& toString(ostream& out) const; virtual ostream& toString(ostream& out) const;
virtual MTGMomirRule * clone() const;
}; };
/* LifeLink */ /* LifeLink */
class MTGLifelinkRule:public MTGAbility{ class MTGLifelinkRule:public MTGAbility{
public: public:
MTGLifelinkRule(int _id):MTGAbility(_id,NULL){}; MTGLifelinkRule(int _id);
int receiveEvent(WEvent * event){ int receiveEvent(WEvent * event);
if (event->type == WEvent::DAMAGE){
WEventDamage * e = (WEventDamage *) event;
Damage * d = e->damage;
MTGCardInstance * card = d->source;
if (d->damage>0 && card && card->basicAbilities[Constants::LIFELINK]){
card->controller()->life+= d->damage;
return 1;
}
}
return 0;
}
int testDestroy(){return 0;} int testDestroy();
virtual ostream& toString(ostream& out) const virtual ostream& toString(ostream& out) const;
{
out << "MTGLifelinkRule ::: ("; virtual MTGLifelinkRule * clone() const;
return MTGAbility::toString(out) << ")";
}
}; };
@@ -205,6 +138,7 @@ public:
void Render(); void Render();
HUDDisplay(int _id); HUDDisplay(int _id);
~HUDDisplay(); ~HUDDisplay();
virtual HUDDisplay * clone() const;
}; };

View File

@@ -27,7 +27,7 @@ class TargetsList{
Interruptible * getNextInterruptible(Interruptible * previous, int type); Interruptible * getNextInterruptible(Interruptible * previous, int type);
Spell * getNextSpellTarget(Spell * previous = 0); Spell * getNextSpellTarget(Spell * previous = 0);
Damage * getNextDamageTarget(Damage * previous = 0); Damage * getNextDamageTarget(Damage * previous = 0);
Targetable * getNextTarget(Targetable * previous, int type); Targetable * getNextTarget(Targetable * previous = 0, int type = -1);
void initTargets(){cursor = 0;}; void initTargets(){cursor = 0;};
}; };

View File

@@ -15,13 +15,13 @@ AIMomirPlayer::AIMomirPlayer(MTGPlayerCards * _deck, char * file, char * fileSma
} }
int AIMomirPlayer::getEfficiency(AIAction * action){ int AIMomirPlayer::getEfficiency(AIAction * action){
MTGAbility * ability = action->ability;
if (ability->cost && !(ability->cost->isExtraPaymentSet())) return 0; //Does not handle abilities with sacrifice yet
int efficiency = AIPlayerBaka::getEfficiency(action);
GameObserver * g = GameObserver::GetInstance();
int efficiency = AIPlayerBaka::getEfficiency(action); if (g->getCurrentGamePhase() < Constants::MTG_PHASE_FIRSTMAIN) return 0;
return efficiency;
GameObserver * g = GameObserver::GetInstance();
if (g->getCurrentGamePhase() < Constants::MTG_PHASE_FIRSTMAIN) return 0;
return efficiency;
} }
MTGAbility * AIMomirPlayer::getMomirAbility(){ MTGAbility * AIMomirPlayer::getMomirAbility(){
@@ -113,81 +113,4 @@ the general rule is this: if you want to get to Eight, you have to skip two drop
return AIPlayerBaka::computeActions(); return AIPlayerBaka::computeActions();
} }
/*
int AIPlayerBaka::computeActions(){
GameObserver * g = GameObserver::GetInstance();
Player * p = g->currentPlayer;
if (!(g->currentlyActing() == this)) return 0;
if (chooseTarget()) return 1;
int currentGamePhase = g->getCurrentGamePhase();
if (g->isInterrupting == this){ // interrupting
selectAbility();
return 1;
}else if (p == this && g->mLayers->stackLayer()->count(0,NOT_RESOLVED) == 0){ //standard actions
CardDescriptor cd;
MTGCardInstance * card = NULL;
switch(currentGamePhase){
case Constants::MTG_PHASE_FIRSTMAIN:
case Constants::MTG_PHASE_SECONDMAIN:
if (canPutLandsIntoPlay){
//Attempt to put land into play
cd.init();
cd.setColor(Constants::MTG_COLOR_LAND);
card = cd.match(game->hand);
if (card){
AIAction * a = NEW AIAction(card);
clickstream.push(a);
return 1;
}
}
//No mana, try to get some
getPotentialMana();
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)
char buffe[4096];
sprintf(buffe, "Putting Card Into Play: %s", nextCardToPlay->getName());
OutputDebugString(buffe);
#endif
tapLandsForMana(potentialMana,nextCardToPlay->getManaCost());
AIAction * a = NEW AIAction(nextCardToPlay);
clickstream.push(a);
return 1;
}else{
selectAbility();
}
}else{
selectAbility();
}
break;
case Constants::MTG_PHASE_COMBATATTACKERS:
chooseAttackers();
break;
default:
selectAbility();
break;
}
}else{
switch(currentGamePhase){
case Constants::MTG_PHASE_COMBATBLOCKERS:
chooseBlockers();
break;
default:
break;
}
return 1;
}
return 1;
};
*/

View File

@@ -135,17 +135,29 @@ int AIAction::getEfficiency(){
ActionStack * s = g->mLayers->stackLayer(); ActionStack * s = g->mLayers->stackLayer();
Player * p = g->currentlyActing(); Player * p = g->currentlyActing();
if (s->has(ability)) return 0; if (s->has(ability)) return 0;
if (ability->cost && !(ability->cost->isExtraPaymentSet())) return 0; //Does not handle abilities with sacrifice yet
switch (ability->aType){ MTGAbility * a = ability;
GenericTargetAbility * gta = dynamic_cast<GenericTargetAbility*>(a);
if (gta) a = gta->ability;
GenericActivatedAbility * gaa = dynamic_cast<GenericActivatedAbility*>(a);
if (gaa) a = gaa->ability;
if (!a){
OutputDebugString("FATAL: Ability is NULL in AIAction::getEfficiency()");
return 0;
}
switch (a->aType){
case MTGAbility::DAMAGER: case MTGAbility::DAMAGER:
{ {
ADamager * a = (ADamager *) ability; AADamager * aad = (AADamager *) a;
if ( p == target->controller()){ if ( p == target->controller()){
efficiency = 0; efficiency = 0;
}else if (a->damage >= target->toughness){ }else if (aad->damage >= target->toughness){
efficiency = 100; efficiency = 100;
}else if (target->toughness){ }else if (target->toughness){
efficiency = (100 * a->damage) / target->toughness; efficiency = (50 * aad->damage) / target->toughness;
}else{ }else{
efficiency = 0; efficiency = 0;
} }
@@ -153,22 +165,12 @@ int AIAction::getEfficiency(){
} }
case MTGAbility::STANDARD_REGENERATE: case MTGAbility::STANDARD_REGENERATE:
{ {
MTGCardInstance * _target = (MTGCardInstance *)(ability->target); MTGCardInstance * _target = (MTGCardInstance *)(a->target);
PutInGraveyard * action = ((PutInGraveyard *) g->mLayers->stackLayer()->getNext(NULL,ACTION_PUTINGRAVEYARD,NOT_RESOLVED)); efficiency = 0;
int i = 0; if (!_target->regenerateTokens && g->getCurrentGamePhase()< Constants::MTG_PHASE_COMBATDAMAGE && (_target->defenser || _target->blockers.size())){
while(action){ efficiency = 95;
i++;
if (action->card == _target){
efficiency = 95;
action = NULL;
}else{
action = ((PutInGraveyard *) g->mLayers->stackLayer()->getNext(action,ACTION_PUTINGRAVEYARD,NOT_RESOLVED));
}
} }
char buf[4096]; //TODO If the card is the target of a damage spell
sprintf(buf,"Graveyard : %i\n", i);
OutputDebugString(buf);
if (efficiency == -1) efficiency = 0;
break; break;
} }
case MTGAbility::MANA_PRODUCER: //can't use mana producers right now :/ case MTGAbility::MANA_PRODUCER: //can't use mana producers right now :/
@@ -741,125 +743,3 @@ int AIPlayerBaka::Act(float dt){
return 1; return 1;
}; };
/*
int AIPlayerBaka::Act(float dt){
GameObserver * gameObs = GameObserver::GetInstance();
int currentGamePhase = gameObs->getCurrentGamePhase();
if (currentGamePhase == Constants::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-= dt;
if (AManaProducer::currentlyTapping || timer>0){
return 0;
}
initTimer();
checkInterrupt();
if (currentAbility) return (useAbility());
if (combatDamages()) return 0;
if (chooseTarget()) return 0;
Player * currentPlayer = gameObs->currentPlayer;
CardDescriptor cd;
if (currentPlayer == this){
MTGCardInstance * card = NULL;
switch(currentGamePhase){
case Constants::MTG_PHASE_FIRSTMAIN:
case Constants::MTG_PHASE_SECONDMAIN:
if (canPutLandsIntoPlay){
//Attempt to put land into play
cd.init();
cd.setColor(Constants::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 (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)
char buffe[4096];
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 Constants::MTG_PHASE_COMBATATTACKERS:
chooseAttackers();
gameObs->userRequestNextGamePhase();
break;
default:
gameObs->userRequestNextGamePhase();
break;
}
}else{
switch(currentGamePhase){
case Constants::MTG_PHASE_COMBATBLOCKERS:
chooseBlockers();
gameObs->userRequestNextGamePhase();
break;
default:
break;
}
return 1;
}
return 1;
}
*/

View File

@@ -10,10 +10,13 @@ ActionElement::ActionElement(int id):JGuiObject(id){
currentPhase = -1; currentPhase = -1;
newPhase = -1; newPhase = -1;
tc = NULL; tc = NULL;
isClone = 0;
} }
ActionElement::~ActionElement(){ ActionElement::~ActionElement(){
SAFE_DELETE(tc); if (!isClone){
SAFE_DELETE(tc);
}
} }
int ActionElement::getActivity(){ int ActionElement::getActivity(){

View File

@@ -71,8 +71,7 @@ void ActionLayer::Update(float dt){
if (mObjects[i]!= NULL){ if (mObjects[i]!= NULL){
ActionElement * currentAction = (ActionElement *)mObjects[i]; ActionElement * currentAction = (ActionElement *)mObjects[i];
if (currentAction->testDestroy()){ if (currentAction->testDestroy()){
currentAction->destroy(); game->removeObserver(currentAction);
Remove(currentAction);
} }
} }
} }

View File

@@ -24,6 +24,12 @@ void UntapBlocker::init(ManaCost * _cost){
manaCost = _cost; manaCost = _cost;
} }
UntapBlocker * UntapBlocker::clone() const{
UntapBlocker * a = NEW UntapBlocker(*this);
a->isClone = 1;
return a;
}
//Default behaviour for blockers : they block the card they're attached to //Default behaviour for blockers : they block the card they're attached to
void UntapBlocker::Update(float dt){ void UntapBlocker::Update(float dt){

View File

@@ -152,7 +152,6 @@ int GameObserver::cancelCurrentAction(){
} }
void GameObserver::userRequestNextGamePhase(){ void GameObserver::userRequestNextGamePhase(){
OutputDebugString("requesting Next Phase\n");
if (mLayers->stackLayer()->getNext(NULL,0,NOT_RESOLVED)) return; if (mLayers->stackLayer()->getNext(NULL,0,NOT_RESOLVED)) return;
if (getCurrentTargetChooser()) return; if (getCurrentTargetChooser()) return;
if (mLayers->combatLayer()->isDisplayed()) return; if (mLayers->combatLayer()->isDisplayed()) return;
@@ -164,7 +163,6 @@ void GameObserver::userRequestNextGamePhase(){
return; return;
} }
} }
OutputDebugString("Next Phase Accepted\n");
if (cPhaseOld->id == Constants::MTG_PHASE_COMBATBLOCKERS || if (cPhaseOld->id == Constants::MTG_PHASE_COMBATBLOCKERS ||
opponent()->isAI() || opponent()->isAI() ||
GameOptions::GetInstance()->values[GameOptions::phaseInterrupts[currentGamePhase]].getIntValue()){ GameOptions::GetInstance()->values[GameOptions::phaseInterrupts[currentGamePhase]].getIntValue()){
@@ -241,11 +239,14 @@ void GameObserver::addObserver(MTGAbility * observer){
void GameObserver::removeObserver(ActionElement * observer){ void GameObserver::removeObserver(ActionElement * observer){
if (observer){ if (observer){
observer->destroy(); if (mLayers->actionLayer()->getIndexOf(observer) != -1){
observer->destroy();
mLayers->actionLayer()->Remove(observer);
}
}else{ }else{
//TODO log error //TODO log error
} }
mLayers->actionLayer()->Remove(observer);
} }
GameObserver::~GameObserver(){ GameObserver::~GameObserver(){

View File

@@ -21,7 +21,7 @@ void GuiLayer::Add(JGuiObject *object){
mCount++; mCount++;
} }
void GuiLayer::Remove(JGuiObject *object){ int GuiLayer::Remove(JGuiObject *object){
for (int i=0;i<mCount;i++){ for (int i=0;i<mCount;i++){
if (mObjects[i]==object){ if (mObjects[i]==object){
delete mObjects[i]; delete mObjects[i];
@@ -29,9 +29,10 @@ void GuiLayer::Remove(JGuiObject *object){
mCount--; mCount--;
if (mCurr == mCount) if (mCurr == mCount)
mCurr = 0; mCurr = 0;
return; return 1;
} }
} }
return 0;
} }
int GuiLayer::getMaxId(){ int GuiLayer::getMaxId(){

File diff suppressed because it is too large Load Diff

View File

@@ -135,7 +135,7 @@ int MTGCardInstance::afterDamage(){
if (!doDamageTest) return 0; if (!doDamageTest) return 0;
doDamageTest = 0; doDamageTest = 0;
if (!isACreature()) return 0; if (!isACreature()) return 0;
if (life <=0 && isInPlay() && !basicAbilities[Constants::INDESTRUCTIBLE]){ if (life <=0 && isInPlay()){
return destroy(); return destroy();
} }
return 0; return 0;
@@ -145,11 +145,12 @@ int MTGCardInstance::bury(){
Player * p = controller(); Player * p = controller();
if (!basicAbilities[Constants::INDESTRUCTIBLE]){ if (!basicAbilities[Constants::INDESTRUCTIBLE]){
p->game->putInZone(this,p->game->inPlay,owner->game->graveyard); p->game->putInZone(this,p->game->inPlay,owner->game->graveyard);
return 1;
} }
return 1; return 0;
} }
int MTGCardInstance::destroy(){ int MTGCardInstance::destroy(){
if (!triggerRegenerate() || !basicAbilities[Constants::INDESTRUCTIBLE]) return bury(); if (!triggerRegenerate()) return bury();
return 0; return 0;
} }

View File

@@ -54,6 +54,12 @@ bool MTGGamePhase::CheckUserInput(u32 key){
return false; return false;
} }
MTGGamePhase * MTGGamePhase::clone() const{
MTGGamePhase * a = NEW MTGGamePhase(*this);
a->isClone = 1;
return a;
}
ostream& MTGGamePhase::toString(ostream& out) const ostream& MTGGamePhase::toString(ostream& out) const
{ {
return out << "MTGGamePhase ::: animation " << animation << " ; currentState : " << currentState; return out << "MTGGamePhase ::: animation " << animation << " ; currentState : " << currentState;

View File

@@ -84,6 +84,12 @@ ostream& MTGPutInPlayRule::toString(ostream& out) const
return MTGAbility::toString(out) << ")"; return MTGAbility::toString(out) << ")";
} }
MTGPutInPlayRule * MTGPutInPlayRule::clone() const{
MTGPutInPlayRule * a = NEW MTGPutInPlayRule(*this);
a->isClone = 1;
return a;
}
MTGAttackRule::MTGAttackRule(int _id):MTGAbility(_id,NULL){ MTGAttackRule::MTGAttackRule(int _id):MTGAbility(_id,NULL){
aType=MTGAbility::MTG_ATTACK_RULE; aType=MTGAbility::MTG_ATTACK_RULE;
@@ -126,6 +132,13 @@ ostream& MTGAttackRule::toString(ostream& out) const
return MTGAbility::toString(out) << ")"; return MTGAbility::toString(out) << ")";
} }
MTGAttackRule * MTGAttackRule::clone() const{
MTGAttackRule * a = NEW MTGAttackRule(*this);
a->isClone = 1;
return a;
}
MTGBlockRule::MTGBlockRule(int _id):MTGAbility(_id,NULL){ MTGBlockRule::MTGBlockRule(int _id):MTGAbility(_id,NULL){
aType=MTGAbility::MTG_BLOCK_RULE; aType=MTGAbility::MTG_BLOCK_RULE;
} }
@@ -167,7 +180,11 @@ ostream& MTGBlockRule::toString(ostream& out) const
return MTGAbility::toString(out) << ")"; return MTGAbility::toString(out) << ")";
} }
MTGBlockRule * MTGBlockRule::clone() const{
MTGBlockRule * a = NEW MTGBlockRule(*this);
a->isClone = 1;
return a;
}
// //
// Attacker chooses blockers order // Attacker chooses blockers order
// //
@@ -295,6 +312,12 @@ ostream& MTGMomirRule::toString(ostream& out) const
} }
MTGMomirRule * MTGMomirRule::clone() const{
MTGMomirRule * a = NEW MTGMomirRule(*this);
a->isClone = 1;
return a;
}
//HUDDisplay //HUDDisplay
int HUDDisplay::testDestroy(){ int HUDDisplay::testDestroy(){
return 0; return 0;
@@ -383,4 +406,125 @@ HUDDisplay::~HUDDisplay(){
delete hs; delete hs;
} }
events.clear(); events.clear();
} }
HUDDisplay * HUDDisplay::clone() const{
HUDDisplay * a = NEW HUDDisplay(*this);
a->isClone = 1;
return a;
}
/* Persist */
MTGPersistRule::MTGPersistRule(int _id):MTGAbility(_id,NULL){};
int MTGPersistRule::receiveEvent(WEvent * event){
if (event->type == WEvent::CHANGE_ZONE){
WEventZoneChange * e = (WEventZoneChange *) event;
MTGCardInstance * card = e->card->previous;
if (card && card->basicAbilities[Constants::PERSIST] && !card->counters->hasCounter(-1,-1)){
int ok = 0;
for (int i = 0; i < 2 ; i++){
Player * p = game->players[i];
if (e->from == p->game->inPlay) ok = 1;
}
if (!ok) return 0;
for (int i = 0; i < 2 ; i++){
Player * p = game->players[i];
if (e->to == p->game->graveyard){
//p->game->putInZone(card, p->game->graveyard, card->owner->game->hand);
MTGCardInstance * copy = p->game->putInZone(e->card, p->game->graveyard, e->card->owner->game->stack);
Spell * spell = NEW Spell(copy);
spell->resolve();
spell->source->counters->addCounter(-1,-1);
game->mLayers->playLayer()->forceUpdateCards();
delete spell;
return 1;
}
}
}
}
return 0;
}
ostream& MTGPersistRule::toString(ostream& out) const
{
out << "MTGPersistRule ::: (";
return MTGAbility::toString(out) << ")";
}
int MTGPersistRule::testDestroy(){return 0;}
MTGPersistRule * MTGPersistRule::clone() const{
MTGPersistRule * a = NEW MTGPersistRule(*this);
a->isClone = 1;
return a;
}
/* Legend Rule */
MTGLegendRule::MTGLegendRule(int _id):ListMaintainerAbility(_id){};
int MTGLegendRule::canBeInList(MTGCardInstance * card){
if (card->basicAbilities[Constants::LEGENDARY] && game->isInPlay(card)){
return 1;
}
return 0;
}
int MTGLegendRule::added(MTGCardInstance * card){
map<MTGCardInstance *,bool>::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 MTGLegendRule::removed(MTGCardInstance * card){return 0;}
int MTGLegendRule::testDestroy(){return 0;}
ostream& MTGLegendRule::toString(ostream& out) const
{
return out << "MTGLegendRule :::";
}
MTGLegendRule * MTGLegendRule::clone() const{
MTGLegendRule * a = NEW MTGLegendRule(*this);
a->isClone = 1;
return a;
}
/* Lifelink */
MTGLifelinkRule::MTGLifelinkRule(int _id):MTGAbility(_id,NULL){};
int MTGLifelinkRule::receiveEvent(WEvent * event){
if (event->type == WEvent::DAMAGE){
WEventDamage * e = (WEventDamage *) event;
Damage * d = e->damage;
MTGCardInstance * card = d->source;
if (d->damage>0 && card && card->basicAbilities[Constants::LIFELINK]){
card->controller()->life+= d->damage;
return 1;
}
}
return 0;
}
int MTGLifelinkRule::testDestroy(){return 0;}
ostream& MTGLifelinkRule::toString(ostream& out) const
{
out << "MTGLifelinkRule ::: (";
return MTGAbility::toString(out) << ")";
}
MTGLifelinkRule * MTGLifelinkRule::clone() const{
MTGLifelinkRule * a = NEW MTGLifelinkRule(*this);
a->isClone = 1;
return a;
}

View File

@@ -282,9 +282,6 @@ int ManaCost::canAfford(ManaCost * _cost){
int positive = diff->isPositive(); int positive = diff->isPositive();
delete diff; delete diff;
if (positive){ if (positive){
#if defined (WIN32) || defined (LINUX)
OutputDebugString("can afford\n");
#endif
return 1; return 1;
} }
return 0; return 0;

View File

@@ -58,11 +58,11 @@ int TargetsList::toggleTarget(Targetable * target){
} }
Targetable * TargetsList::getNextTarget(Targetable * previous, int type){ Targetable * TargetsList::getNextTarget(Targetable * previous , int type){
int found = 0; int found = 0;
if (!previous) found = 1; if (!previous) found = 1;
for (int i = 0; i < cursor; i++){ for (int i = 0; i < cursor; i++){
if (found && targets[i]->typeAsTarget() == type){ if (found && (type == -1 || targets[i]->typeAsTarget() == type)){
return (targets[i]); return (targets[i]);
} }
if (targets[i] == previous) found = 1; if (targets[i] == previous) found = 1;

View File

@@ -119,6 +119,11 @@ int TestSuiteAI::Act(float dt){
MTGMomirRule * a = ((MTGMomirRule *)g->mLayers->actionLayer()->getAbility(MTGAbility::MOMIR)); MTGMomirRule * a = ((MTGMomirRule *)g->mLayers->actionLayer()->getAbility(MTGAbility::MOMIR));
a->reactToClick(suite->getCardByMTGId(cardIdHand), cardId); a->reactToClick(suite->getCardByMTGId(cardIdHand), cardId);
g->mLayers->actionLayer()->stuffHappened = 1; g->mLayers->actionLayer()->stuffHappened = 1;
}else if(action.find("p1")!=string::npos || action.find("p2")!=string::npos){
Player * p = g->players[1];
int start = action.find("p1");
if (start != string::npos) p = g->players[0];
g->cardClick(NULL, p);
}else{ }else{
int mtgid = suite->getMTGId(action); int mtgid = suite->getMTGId(action);
if (mtgid){ if (mtgid){