Erwan
- 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:
@@ -501,6 +501,7 @@ mana={W}
|
||||
text={B}{B}: Counter target green spell.
|
||||
id=1151
|
||||
name=Deathgrip
|
||||
auto={B}{B}:fizzle target(*[green]|stack)
|
||||
rarity=U
|
||||
type=Enchantment
|
||||
mana={B}{B}
|
||||
@@ -1251,6 +1252,7 @@ toughness=1
|
||||
text={G}{G}: Counter target black spell.
|
||||
id=1256
|
||||
name=Lifeforce
|
||||
auto={G}{G}:fizzle target(*[black]|stack)
|
||||
rarity=U
|
||||
type=Enchantment
|
||||
mana={G}{G}
|
||||
|
||||
@@ -13,6 +13,8 @@ generic/legendary.txt
|
||||
generic/lifelink.txt
|
||||
generic/persist.txt
|
||||
generic/persist2.txt
|
||||
generic/rampage.txt
|
||||
generic/regenerate.txt
|
||||
generic/sacrifice.txt
|
||||
generic/wither.txt
|
||||
########################
|
||||
@@ -22,6 +24,7 @@ afflict.txt
|
||||
akron_legionnaire.txt
|
||||
Amugaba.txt
|
||||
anarchy.txt
|
||||
ancestors_chosen.txt
|
||||
animate_dead.txt
|
||||
animate_dead2.txt
|
||||
animate_dead3.txt
|
||||
@@ -57,6 +60,7 @@ counterspell3.txt
|
||||
counterspell4.txt
|
||||
creature_bond.txt
|
||||
dauthi_embrace.txt
|
||||
death_ward.txt
|
||||
deja_vu.txt
|
||||
dingus_egg.txt
|
||||
doomed_necromancer.txt
|
||||
@@ -76,12 +80,14 @@ fountain_of_youth.txt
|
||||
ghost_warden.txt
|
||||
giant_growth.txt
|
||||
giant_growth2.txt
|
||||
glimpse_the_unthinkable.txt
|
||||
goblin_balloon_brigade.txt
|
||||
goblin_balloon_brigade2.txt
|
||||
goblin_king.txt
|
||||
gravedigger.txt
|
||||
#hammerfist_giant.txt
|
||||
hannas_custody.txt
|
||||
howl_of_the_night_pack.txt
|
||||
hymn_of_rebirth.txt
|
||||
icatian_priest.txt
|
||||
keldon_warlord.txt
|
||||
@@ -95,6 +101,8 @@ living_lands.txt
|
||||
lord_of_the_pit.txt
|
||||
lord_of_the_pit2.txt
|
||||
master_of_etherium.txt
|
||||
millstone.txt
|
||||
mind_rot.txt
|
||||
nantuko_husk.txt
|
||||
Nevinyrrals_Disk.txt
|
||||
Nevinyrrals_Disk2.txt
|
||||
@@ -118,8 +126,10 @@ siege_gang_commander.txt
|
||||
shivan_hellkite.txt
|
||||
shock.txt
|
||||
sphinx_summoner.txt
|
||||
spitting_earth.txt
|
||||
spark_elemental.txt
|
||||
spirit_link.txt
|
||||
spoils_of_evil.txt
|
||||
stasis.txt
|
||||
steelclad_serpent1.txt
|
||||
steelclad_serpent2.txt
|
||||
|
||||
21
projects/mtg/bin/Res/test/ancestors_chosen.txt
Normal file
21
projects/mtg/bin/Res/test/ancestors_chosen.txt
Normal 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]
|
||||
26
projects/mtg/bin/Res/test/death_ward.txt
Normal file
26
projects/mtg/bin/Res/test/death_ward.txt
Normal 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]
|
||||
20
projects/mtg/bin/Res/test/generic/rampage.txt
Normal file
20
projects/mtg/bin/Res/test/generic/rampage.txt
Normal 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]
|
||||
22
projects/mtg/bin/Res/test/generic/regenerate.txt
Normal file
22
projects/mtg/bin/Res/test/generic/regenerate.txt
Normal 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]
|
||||
20
projects/mtg/bin/Res/test/glimpse_the_unthinkable.txt
Normal file
20
projects/mtg/bin/Res/test/glimpse_the_unthinkable.txt
Normal 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]
|
||||
18
projects/mtg/bin/Res/test/howl_of_the_night_pack.txt
Normal file
18
projects/mtg/bin/Res/test/howl_of_the_night_pack.txt
Normal 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]
|
||||
20
projects/mtg/bin/Res/test/millstone.txt
Normal file
20
projects/mtg/bin/Res/test/millstone.txt
Normal 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]
|
||||
20
projects/mtg/bin/Res/test/mind_rot.txt
Normal file
20
projects/mtg/bin/Res/test/mind_rot.txt
Normal 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]
|
||||
22
projects/mtg/bin/Res/test/spitting_earth.txt
Normal file
22
projects/mtg/bin/Res/test/spitting_earth.txt
Normal 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]
|
||||
20
projects/mtg/bin/Res/test/spoils_of_evil.txt
Normal file
20
projects/mtg/bin/Res/test/spoils_of_evil.txt
Normal 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]
|
||||
@@ -22,10 +22,11 @@ class WEvent;
|
||||
class ActionElement: public JGuiObject{
|
||||
protected:
|
||||
int activeState;
|
||||
|
||||
|
||||
|
||||
|
||||
public:
|
||||
int isClone;
|
||||
TargetChooser * tc;
|
||||
int currentPhase;
|
||||
int newPhase;
|
||||
@@ -46,6 +47,7 @@ class ActionElement: public JGuiObject{
|
||||
virtual int receiveEvent(WEvent * event){return 0;};
|
||||
virtual int reactToClick(MTGCardInstance * card){return 0;};
|
||||
virtual const char * getMenuText(){return "Ability";};
|
||||
virtual ActionElement * clone() const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -27,6 +27,7 @@ class UntapBlocker : public MTGAbility {
|
||||
~UntapBlocker();
|
||||
virtual void Update(float dt);
|
||||
virtual int destroy();
|
||||
virtual UntapBlocker * clone() const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ class GuiLayer{
|
||||
int mCurr;
|
||||
vector<JGuiObject *>mObjects;
|
||||
void Add(JGuiObject * object);
|
||||
void Remove(JGuiObject * object);
|
||||
int Remove(JGuiObject * object);
|
||||
int modal;
|
||||
bool hasFocus;
|
||||
virtual void resetObjects();
|
||||
|
||||
@@ -19,15 +19,18 @@ class WEvent;
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <hge/hgeparticle.h>
|
||||
#include "../include/Damage.h"
|
||||
using std::string;
|
||||
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 ?
|
||||
#define BAKA_EFFECT_GOOD 1
|
||||
#define BAKA_EFFECT_BAD -1
|
||||
#define BAKA_EFFECT_DONTKNOW 0
|
||||
#define MODE_PUTINTOPLAY 1
|
||||
#define MODE_ABILITY 2
|
||||
|
||||
#define COUNT_POWER 1
|
||||
|
||||
@@ -38,16 +41,17 @@ using std::map;
|
||||
class MTGAbility: public ActionElement{
|
||||
protected:
|
||||
char menuText[25];
|
||||
|
||||
|
||||
GameObserver * game;
|
||||
public:
|
||||
int oneShot;
|
||||
int forceDestroy;
|
||||
ManaCost * cost;
|
||||
Damageable * target;
|
||||
Targetable * target;
|
||||
int aType;
|
||||
MTGCardInstance * source;
|
||||
MTGAbility(int id, MTGCardInstance * card);
|
||||
MTGAbility(int id, MTGCardInstance * _source, Damageable * _target);
|
||||
MTGAbility(int id, MTGCardInstance * _source, Targetable * _target);
|
||||
virtual int testDestroy();
|
||||
virtual ~MTGAbility();
|
||||
virtual void Render(){};
|
||||
@@ -58,7 +62,10 @@ class MTGAbility: public ActionElement{
|
||||
virtual int fireAbility();
|
||||
virtual int stillInUse(MTGCardInstance * card){if (card==source) return 1; return 0;};
|
||||
virtual int resolve(){return 0;};
|
||||
virtual MTGAbility* clone() const = 0;
|
||||
virtual ostream& toString(ostream& out) const;
|
||||
virtual int addToGame();
|
||||
virtual int removeFromGame();
|
||||
|
||||
/*Poor man's casting */
|
||||
/* Todo replace that crap with dynamic casting */
|
||||
@@ -78,11 +85,12 @@ class MTGAbility: public ActionElement{
|
||||
class TriggeredAbility:public MTGAbility{
|
||||
public:
|
||||
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 Render(){};
|
||||
virtual int trigger()=0;
|
||||
virtual int resolve() = 0;
|
||||
virtual TriggeredAbility* clone() const = 0;
|
||||
virtual ostream& toString(ostream& out) const;
|
||||
};
|
||||
|
||||
@@ -96,18 +104,24 @@ class ActivatedAbility:public MTGAbility{
|
||||
virtual int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
|
||||
virtual int reactToTargetClick(Targetable * object);
|
||||
virtual int resolve() = 0;
|
||||
virtual ActivatedAbility* clone() const = 0;
|
||||
virtual ostream& toString(ostream& out) const;
|
||||
};
|
||||
|
||||
class TargetAbility:public ActivatedAbility{
|
||||
public:
|
||||
MTGAbility * ability;
|
||||
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 TargetAbility* clone() const = 0;
|
||||
virtual void Render();
|
||||
virtual int resolve();
|
||||
virtual const char * getMenuText();
|
||||
virtual ostream& toString(ostream& out) const;
|
||||
~TargetAbility();
|
||||
};
|
||||
|
||||
class InstantAbility:public MTGAbility{
|
||||
@@ -118,6 +132,7 @@ class InstantAbility:public MTGAbility{
|
||||
InstantAbility(int _id, MTGCardInstance * source);
|
||||
InstantAbility(int _id, MTGCardInstance * source,Damageable * _target);
|
||||
virtual int resolve(){return 0;};
|
||||
virtual InstantAbility* clone() const = 0;
|
||||
virtual ostream& toString(ostream& out) const;
|
||||
};
|
||||
|
||||
@@ -125,26 +140,32 @@ class InstantAbility:public MTGAbility{
|
||||
class ListMaintainerAbility:public MTGAbility{
|
||||
public:
|
||||
map<MTGCardInstance *,bool> cards;
|
||||
map<Player *,bool> players;
|
||||
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);
|
||||
void updateTargets();
|
||||
virtual int canBeInList(MTGCardInstance * card) = 0;
|
||||
virtual int added(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 ListMaintainerAbility* clone() const = 0;
|
||||
virtual ostream& toString(ostream& out) const;
|
||||
};
|
||||
|
||||
/* An attempt to globalize triggered abilities as much as possible */
|
||||
class MTGAbilityBasicFeatures{
|
||||
public:
|
||||
Damageable * target;
|
||||
Targetable * target;
|
||||
GameObserver * game;
|
||||
MTGCardInstance * source;
|
||||
MTGAbilityBasicFeatures();
|
||||
MTGAbilityBasicFeatures(MTGCardInstance * _source, Damageable * _target = NULL);
|
||||
void init(MTGCardInstance * _source, Damageable * _target = NULL);
|
||||
MTGAbilityBasicFeatures(MTGCardInstance * _source, Targetable * _target = NULL);
|
||||
void init(MTGCardInstance * _source, Targetable * _target = NULL);
|
||||
};
|
||||
|
||||
class Trigger:public MTGAbilityBasicFeatures{
|
||||
@@ -176,7 +197,7 @@ class TriggerNextPhase:public TriggerAtPhase{
|
||||
class TriggeredEvent:public MTGAbilityBasicFeatures{
|
||||
public:
|
||||
TriggeredEvent();
|
||||
TriggeredEvent(MTGCardInstance * source, Damageable * target = NULL);
|
||||
TriggeredEvent(MTGCardInstance * source, Targetable * target = NULL);
|
||||
virtual int resolve()=0;
|
||||
};
|
||||
|
||||
@@ -213,21 +234,22 @@ class GenericTriggeredAbility:public TriggeredAbility{
|
||||
Trigger * t;
|
||||
TriggeredEvent * te;
|
||||
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 resolve();
|
||||
virtual int testDestroy();
|
||||
virtual GenericTriggeredAbility* clone() const;
|
||||
~GenericTriggeredAbility();
|
||||
};
|
||||
|
||||
/* Ability Factory */
|
||||
class AbilityFactory{
|
||||
private:
|
||||
int countCards(TargetChooser * tc, Player * player = NULL, int option = 0);
|
||||
int putInPlayFromZone(MTGCardInstance * card, MTGGameZone * zone, Player * p);
|
||||
int countCards(TargetChooser * tc, Player * player = NULL, int option = 0);
|
||||
int parsePowerToughness(string s, int *power, int *toughness);
|
||||
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:
|
||||
int magicText(int id, Spell * spell, MTGCardInstance * card = NULL);
|
||||
int destroyAllInPlay(TargetChooser * tc, int bury = 0);
|
||||
@@ -243,16 +265,16 @@ class AbilityFactory{
|
||||
class AManaProducer: public MTGAbility{
|
||||
protected:
|
||||
|
||||
ManaCost * cost;
|
||||
ManaCost * output;
|
||||
string menutext;
|
||||
float x0,y0,x1,y1,x,y;
|
||||
float animation;
|
||||
Player * controller;
|
||||
int tap;
|
||||
|
||||
|
||||
hgeParticleSystem * mParticleSys;
|
||||
public:
|
||||
int tap;
|
||||
static int currentlyTapping;
|
||||
AManaProducer(int id, MTGCardInstance * card, ManaCost * _output, ManaCost * _cost = NULL, int doTap = 1 );
|
||||
void Update(float dt);
|
||||
@@ -263,6 +285,7 @@ class AManaProducer: public MTGAbility{
|
||||
const char * getMenuText();
|
||||
int testDestroy();
|
||||
~AManaProducer();
|
||||
virtual AManaProducer * clone() const;
|
||||
virtual ostream& toString(ostream& out) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ class MTGGamePhase: public ActionElement {
|
||||
virtual void Render();
|
||||
virtual void Update(float dt);
|
||||
bool CheckUserInput(u32 key);
|
||||
virtual MTGGamePhase * clone() const;
|
||||
virtual ostream& toString(ostream& out) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ class MTGPutInPlayRule:public MTGAbility{
|
||||
virtual ostream& toString(ostream& out) const;
|
||||
MTGPutInPlayRule(int _id);
|
||||
const char * getMenuText(){return "Put into play";}
|
||||
virtual MTGPutInPlayRule * clone() const;
|
||||
};
|
||||
|
||||
class MTGAttackRule:public MTGAbility{
|
||||
@@ -27,6 +28,7 @@ class MTGAttackRule:public MTGAbility{
|
||||
MTGAttackRule(int _id);
|
||||
const char * getMenuText(){return "Attacker";}
|
||||
void Update(float dt);
|
||||
virtual MTGAttackRule * clone() const;
|
||||
};
|
||||
|
||||
class MTGBlockRule:public MTGAbility{
|
||||
@@ -37,49 +39,18 @@ class MTGBlockRule:public MTGAbility{
|
||||
virtual ostream& toString(ostream& out) const;
|
||||
MTGBlockRule(int _id);
|
||||
const char * getMenuText(){return "Blocker";}
|
||||
virtual MTGBlockRule * clone() const;
|
||||
};
|
||||
|
||||
|
||||
/* Persist Rule */
|
||||
class MTGPersistRule:public MTGAbility{
|
||||
public:
|
||||
MTGPersistRule(int _id):MTGAbility(_id,NULL){};
|
||||
|
||||
int 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;
|
||||
}
|
||||
|
||||
virtual ostream& toString(ostream& out) const
|
||||
{
|
||||
out << "MTGPersistRule ::: (";
|
||||
return MTGAbility::toString(out) << ")";
|
||||
}
|
||||
int testDestroy(){return 0;}
|
||||
MTGPersistRule(int _id);
|
||||
int receiveEvent(WEvent * event);
|
||||
virtual ostream& toString(ostream& out) const;
|
||||
int testDestroy();
|
||||
virtual MTGPersistRule * clone() const;
|
||||
};
|
||||
|
||||
|
||||
@@ -91,39 +62,13 @@ class MTGPersistRule:public MTGAbility{
|
||||
*/
|
||||
class MTGLegendRule:public ListMaintainerAbility{
|
||||
public:
|
||||
MTGLegendRule(int _id):ListMaintainerAbility(_id){};
|
||||
|
||||
int canBeInList(MTGCardInstance * card){
|
||||
if (card->basicAbilities[Constants::LEGENDARY] && game->isInPlay(card)){
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 :::";
|
||||
}
|
||||
MTGLegendRule(int _id);
|
||||
int canBeInList(MTGCardInstance * card);
|
||||
int added(MTGCardInstance * card);
|
||||
int removed(MTGCardInstance * card);
|
||||
int testDestroy();
|
||||
virtual ostream& toString(ostream& out) const;
|
||||
virtual MTGLegendRule * clone() const;
|
||||
};
|
||||
|
||||
|
||||
@@ -149,34 +94,22 @@ public:
|
||||
int reactToClick(MTGCardInstance * card, int id);
|
||||
const char * getMenuText(){return "Momir";}
|
||||
virtual ostream& toString(ostream& out) const;
|
||||
virtual MTGMomirRule * clone() const;
|
||||
};
|
||||
|
||||
|
||||
/* LifeLink */
|
||||
class MTGLifelinkRule:public MTGAbility{
|
||||
public:
|
||||
MTGLifelinkRule(int _id):MTGAbility(_id,NULL){};
|
||||
MTGLifelinkRule(int _id);
|
||||
|
||||
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 receiveEvent(WEvent * event);
|
||||
|
||||
int testDestroy(){return 0;}
|
||||
int testDestroy();
|
||||
|
||||
virtual ostream& toString(ostream& out) const
|
||||
{
|
||||
out << "MTGLifelinkRule ::: (";
|
||||
return MTGAbility::toString(out) << ")";
|
||||
}
|
||||
virtual ostream& toString(ostream& out) const;
|
||||
|
||||
virtual MTGLifelinkRule * clone() const;
|
||||
};
|
||||
|
||||
|
||||
@@ -205,6 +138,7 @@ public:
|
||||
void Render();
|
||||
HUDDisplay(int _id);
|
||||
~HUDDisplay();
|
||||
virtual HUDDisplay * clone() const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ class TargetsList{
|
||||
Interruptible * getNextInterruptible(Interruptible * previous, int type);
|
||||
Spell * getNextSpellTarget(Spell * 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;};
|
||||
};
|
||||
|
||||
|
||||
@@ -15,13 +15,13 @@ AIMomirPlayer::AIMomirPlayer(MTGPlayerCards * _deck, char * file, char * fileSma
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
||||
int efficiency = AIPlayerBaka::getEfficiency(action);
|
||||
|
||||
GameObserver * g = GameObserver::GetInstance();
|
||||
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(){
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
/*
|
||||
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;
|
||||
};
|
||||
*/
|
||||
|
||||
@@ -135,17 +135,29 @@ int AIAction::getEfficiency(){
|
||||
ActionStack * s = g->mLayers->stackLayer();
|
||||
Player * p = g->currentlyActing();
|
||||
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:
|
||||
{
|
||||
ADamager * a = (ADamager *) ability;
|
||||
AADamager * aad = (AADamager *) a;
|
||||
if ( p == target->controller()){
|
||||
efficiency = 0;
|
||||
}else if (a->damage >= target->toughness){
|
||||
}else if (aad->damage >= target->toughness){
|
||||
efficiency = 100;
|
||||
}else if (target->toughness){
|
||||
efficiency = (100 * a->damage) / target->toughness;
|
||||
efficiency = (50 * aad->damage) / target->toughness;
|
||||
}else{
|
||||
efficiency = 0;
|
||||
}
|
||||
@@ -153,22 +165,12 @@ int AIAction::getEfficiency(){
|
||||
}
|
||||
case MTGAbility::STANDARD_REGENERATE:
|
||||
{
|
||||
MTGCardInstance * _target = (MTGCardInstance *)(ability->target);
|
||||
PutInGraveyard * action = ((PutInGraveyard *) g->mLayers->stackLayer()->getNext(NULL,ACTION_PUTINGRAVEYARD,NOT_RESOLVED));
|
||||
int i = 0;
|
||||
while(action){
|
||||
i++;
|
||||
if (action->card == _target){
|
||||
efficiency = 95;
|
||||
action = NULL;
|
||||
}else{
|
||||
action = ((PutInGraveyard *) g->mLayers->stackLayer()->getNext(action,ACTION_PUTINGRAVEYARD,NOT_RESOLVED));
|
||||
}
|
||||
MTGCardInstance * _target = (MTGCardInstance *)(a->target);
|
||||
efficiency = 0;
|
||||
if (!_target->regenerateTokens && g->getCurrentGamePhase()< Constants::MTG_PHASE_COMBATDAMAGE && (_target->defenser || _target->blockers.size())){
|
||||
efficiency = 95;
|
||||
}
|
||||
char buf[4096];
|
||||
sprintf(buf,"Graveyard : %i\n", i);
|
||||
OutputDebugString(buf);
|
||||
if (efficiency == -1) efficiency = 0;
|
||||
//TODO If the card is the target of a damage spell
|
||||
break;
|
||||
}
|
||||
case MTGAbility::MANA_PRODUCER: //can't use mana producers right now :/
|
||||
@@ -741,125 +743,3 @@ int AIPlayerBaka::Act(float dt){
|
||||
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;
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -10,10 +10,13 @@ ActionElement::ActionElement(int id):JGuiObject(id){
|
||||
currentPhase = -1;
|
||||
newPhase = -1;
|
||||
tc = NULL;
|
||||
isClone = 0;
|
||||
}
|
||||
|
||||
ActionElement::~ActionElement(){
|
||||
SAFE_DELETE(tc);
|
||||
if (!isClone){
|
||||
SAFE_DELETE(tc);
|
||||
}
|
||||
}
|
||||
|
||||
int ActionElement::getActivity(){
|
||||
|
||||
@@ -71,8 +71,7 @@ void ActionLayer::Update(float dt){
|
||||
if (mObjects[i]!= NULL){
|
||||
ActionElement * currentAction = (ActionElement *)mObjects[i];
|
||||
if (currentAction->testDestroy()){
|
||||
currentAction->destroy();
|
||||
Remove(currentAction);
|
||||
game->removeObserver(currentAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,12 @@ void UntapBlocker::init(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
|
||||
void UntapBlocker::Update(float dt){
|
||||
|
||||
@@ -152,7 +152,6 @@ int GameObserver::cancelCurrentAction(){
|
||||
}
|
||||
|
||||
void GameObserver::userRequestNextGamePhase(){
|
||||
OutputDebugString("requesting Next Phase\n");
|
||||
if (mLayers->stackLayer()->getNext(NULL,0,NOT_RESOLVED)) return;
|
||||
if (getCurrentTargetChooser()) return;
|
||||
if (mLayers->combatLayer()->isDisplayed()) return;
|
||||
@@ -164,7 +163,6 @@ void GameObserver::userRequestNextGamePhase(){
|
||||
return;
|
||||
}
|
||||
}
|
||||
OutputDebugString("Next Phase Accepted\n");
|
||||
if (cPhaseOld->id == Constants::MTG_PHASE_COMBATBLOCKERS ||
|
||||
opponent()->isAI() ||
|
||||
GameOptions::GetInstance()->values[GameOptions::phaseInterrupts[currentGamePhase]].getIntValue()){
|
||||
@@ -241,11 +239,14 @@ void GameObserver::addObserver(MTGAbility * observer){
|
||||
|
||||
void GameObserver::removeObserver(ActionElement * observer){
|
||||
if (observer){
|
||||
observer->destroy();
|
||||
if (mLayers->actionLayer()->getIndexOf(observer) != -1){
|
||||
observer->destroy();
|
||||
mLayers->actionLayer()->Remove(observer);
|
||||
}
|
||||
}else{
|
||||
//TODO log error
|
||||
}
|
||||
mLayers->actionLayer()->Remove(observer);
|
||||
|
||||
}
|
||||
|
||||
GameObserver::~GameObserver(){
|
||||
|
||||
@@ -21,7 +21,7 @@ void GuiLayer::Add(JGuiObject *object){
|
||||
mCount++;
|
||||
}
|
||||
|
||||
void GuiLayer::Remove(JGuiObject *object){
|
||||
int GuiLayer::Remove(JGuiObject *object){
|
||||
for (int i=0;i<mCount;i++){
|
||||
if (mObjects[i]==object){
|
||||
delete mObjects[i];
|
||||
@@ -29,9 +29,10 @@ void GuiLayer::Remove(JGuiObject *object){
|
||||
mCount--;
|
||||
if (mCurr == mCount)
|
||||
mCurr = 0;
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GuiLayer::getMaxId(){
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -135,7 +135,7 @@ int MTGCardInstance::afterDamage(){
|
||||
if (!doDamageTest) return 0;
|
||||
doDamageTest = 0;
|
||||
if (!isACreature()) return 0;
|
||||
if (life <=0 && isInPlay() && !basicAbilities[Constants::INDESTRUCTIBLE]){
|
||||
if (life <=0 && isInPlay()){
|
||||
return destroy();
|
||||
}
|
||||
return 0;
|
||||
@@ -145,11 +145,12 @@ int MTGCardInstance::bury(){
|
||||
Player * p = controller();
|
||||
if (!basicAbilities[Constants::INDESTRUCTIBLE]){
|
||||
p->game->putInZone(this,p->game->inPlay,owner->game->graveyard);
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
int MTGCardInstance::destroy(){
|
||||
if (!triggerRegenerate() || !basicAbilities[Constants::INDESTRUCTIBLE]) return bury();
|
||||
if (!triggerRegenerate()) return bury();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,12 @@ bool MTGGamePhase::CheckUserInput(u32 key){
|
||||
return false;
|
||||
}
|
||||
|
||||
MTGGamePhase * MTGGamePhase::clone() const{
|
||||
MTGGamePhase * a = NEW MTGGamePhase(*this);
|
||||
a->isClone = 1;
|
||||
return a;
|
||||
}
|
||||
|
||||
ostream& MTGGamePhase::toString(ostream& out) const
|
||||
{
|
||||
return out << "MTGGamePhase ::: animation " << animation << " ; currentState : " << currentState;
|
||||
|
||||
@@ -84,6 +84,12 @@ ostream& MTGPutInPlayRule::toString(ostream& out) const
|
||||
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){
|
||||
aType=MTGAbility::MTG_ATTACK_RULE;
|
||||
@@ -126,6 +132,13 @@ ostream& MTGAttackRule::toString(ostream& out) const
|
||||
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){
|
||||
aType=MTGAbility::MTG_BLOCK_RULE;
|
||||
}
|
||||
@@ -167,7 +180,11 @@ ostream& MTGBlockRule::toString(ostream& out) const
|
||||
return MTGAbility::toString(out) << ")";
|
||||
}
|
||||
|
||||
|
||||
MTGBlockRule * MTGBlockRule::clone() const{
|
||||
MTGBlockRule * a = NEW MTGBlockRule(*this);
|
||||
a->isClone = 1;
|
||||
return a;
|
||||
}
|
||||
//
|
||||
// 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
|
||||
int HUDDisplay::testDestroy(){
|
||||
return 0;
|
||||
@@ -383,4 +406,125 @@ HUDDisplay::~HUDDisplay(){
|
||||
delete hs;
|
||||
}
|
||||
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;
|
||||
}
|
||||
@@ -282,9 +282,6 @@ int ManaCost::canAfford(ManaCost * _cost){
|
||||
int positive = diff->isPositive();
|
||||
delete diff;
|
||||
if (positive){
|
||||
#if defined (WIN32) || defined (LINUX)
|
||||
OutputDebugString("can afford\n");
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -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;
|
||||
if (!previous) found = 1;
|
||||
for (int i = 0; i < cursor; i++){
|
||||
if (found && targets[i]->typeAsTarget() == type){
|
||||
if (found && (type == -1 || targets[i]->typeAsTarget() == type)){
|
||||
return (targets[i]);
|
||||
}
|
||||
if (targets[i] == previous) found = 1;
|
||||
|
||||
@@ -119,6 +119,11 @@ int TestSuiteAI::Act(float dt){
|
||||
MTGMomirRule * a = ((MTGMomirRule *)g->mLayers->actionLayer()->getAbility(MTGAbility::MOMIR));
|
||||
a->reactToClick(suite->getCardByMTGId(cardIdHand), cardId);
|
||||
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{
|
||||
int mtgid = suite->getMTGId(action);
|
||||
if (mtgid){
|
||||
|
||||
Reference in New Issue
Block a user