im forced to do this commit in whole instead of parts as originally planned, and before my beta test period of the changes is complete BECAUSE there are people doing "clean up" and the MASSIVE amount of conflicts i have to resolve from it is WAY too much for me to take on after nearly 200 hours of coding this patch. i cant seem to get enough respect to have people hold off on "clean up" so this brings me to being forced to do a full commit before playtest period is done, so they can go ahead with there *super important* clean up.
ok i WAS going to write a full change log with code exsamples ect, but since im rushed you will get the short version of this log.
first bug fixes, and there were many,
indestructible creature bug fixed
halimar execavator *embearessing youtube video" bug is fixed
token text now displays source name and tokens abilities
fixed a card view null pointer in an iterator when code used combinations of foreach and aslongas with CD.
epic struggle bug fixed, aslongas was only parsing one space to the right of the operator.
extra cost containing targetting fixed, cards can now have multiple extra cost in all mana...this includes giving a card 2 targeted sacrifices as its main cost.
angelic chorus bug fixed, the card will be soft coded now.
and many other minor bugs fixed, hard to remember all which were fixed.
now, new abilities = words
"legendarylandwalk",
"desertlandwalk",
"snowforestlandwalk",
"snowplainslandwalk",
"snowmountainlandwalk",
"snowislandlandwalk",
"snowswamplandwalk",
"snowlandwalk",
"nonbasiclandwalk",
"strong",//cant be blocked by creature with less power
"weak",//cant block creatures with more power
"phasing",
all true landwalks will now be supported.
new cost types:
morph which is coded as follows
[card]
name=Bloodstoke Howler
facedown={3}
autofacedown={6}{R}:morph
autofaceup=3/0 all(beast|mybattlefield))
text=Morph {6}{R} (You may cast this face down as a 2/2 creature for {3}. Turn it face up any time for its morph cost.) -- When Bloodstoke Howler is turned
face up, Beast creatures you control get +3/+0 until end of turn.
mana={5}{R}
type=Creature
subtype=Beast
power=3
toughness=4
[/card]
you will notice new auto lines autofaceup and autofacedown
these are abilities the cards will have when theyre in that state.
the cost is coded as
facedown={cost}
when a card is faced up it gains auto= lines also.
tho is played normally it will NOT gain autofaceup=lines
card restrictions:
cards can now have restrictions placed on them the restrictions are.
all previous restrictions usable in activated abilities
with the follow additions
control two or more vampires
control less creatures
control snow land
casted a spell
one of a kind
fourth turn
before battle damage
after battle
during battle
[card]
name=Blood Frenzy
target=creature[attacking;blocking]
restriction=before battle damage
auto=4/0
auto=treason
text=Cast Blood Frenzy only before the combat damage step. -- Target attacking or blocking creature gets +4/+0 until end of turn. Destroy that creature
at the beginning of the next end step.
mana={1}{R}
type=Instant
[/card]
other cost now can have specail restrictions also:
otherrestriction=mytypemin:1 type(swamp),opponenttypemin:1 opponenttype(plains)
these are minimums required inplay of a type
it can be just you, or you and opponent or just opponent
you can also use the words "more" and "less" and * to compare the 2 players fields.
[card]
name=Cho-Arrim Legate
abilities=protection from black
other={0}
otherrestriction=mytypemin:1 type(swamp) , opponenttypemin:1 opponenttype(plains)
text=Protection from black -- If an opponent controls a Swamp and you control a Plains, you may cast Cho-Arrim Legate without paying its mana cost.
mana={2}{W}
type=Creature
subtype=Human Soldier
power=1
toughness=2
[/card]
activated ability gained a new restriction "opponentturnonly"
variables will now be recalculated during the resolve of the major abilities to produce the most current number.
{x}:draw:x <----
new number variables words:
using draw as an exsample
draw:auras <--auras on a creature
draw:type:ally <---counts the allys in your field. self explanitory
draw:thatmuch <--mostly a triggered effects number.
when you take damage draw that much
draw:lifelost
draw:oplifelost
these return the value of the life lost that turn.
new TRIGGER restricitions
sourcenottap
sourceTap
foelostthree<--card cycle uses opponent lost life
foelosttwo<--same as above
once<--this trigger will only ever trigger one time and never again.
new card discriptor words
[multicolor]
[leveler]
[enchanted]
[blackandgreen]
[blackandwhite]
[redandblue]
[blueandgreen]
[redandwhite]
CD will now recalculate the number again on resolve
meaning {x}:target(CreatureTargetChooser[manacost <=x]) will work, with an added bonus {x}:target(CreatureTargetChooser[manacost <=any word variable])
new this(:
this(tapped)<--for strange case cards.
this(untapped)
this(auras)
new MTGAbility keywords
(blink)
(blink)forsrc <--stay blinked while source inplay
hand(blink <---adding hand to the front makes it target hand.
livingweapon
this is an extension of token, simple attach the words "livingweapon" to the front of token( and it will autoamtically token that and attach the card to it.
token( gained:
"targetcontroller" targetting.
"battleready" if put in the tokens abilities it will be a attacker and tapped as it is entering play.
phaseout <--self explanitory
spiritlink <--stacking lifelink style effect that benifits the OWNER of the card.
combatspiritlink same as above.
stacking flanking, requires 2 abilities unfortunately
[card]
name=Agility
target=creature
auto=teach(creature) flanker
auto=teach(creature) flanking
text=Enchant creature -- Enchanted creature gets +1/+1 and has flanking. (Whenever a creature without flanking blocks this creature, the blocking
creature gets -1/-1 until end of turn.)
mana={1}{R}
type=Enchantment
subtype=Aura
[/card]
removeallcounters(number/number,name)
removes all counters of the type from a card, can all be
"all"
vampire hexmage effect.
added new tools for transforms
,setpower=number
,settoughness=number
removetypes
morph
autofacedown={0}:morph
eradicate <---same as the card name.
cumulativeupcost[ <--self explanitory
upcostmulti[ <--an upcost that will resolve with a && ability
phaseaction[ phase name ] ability
an ability that will trigger on the stated phase name.
also support for phaseactionmulti[
new triggers added:
@vampired( <--sengir vampire effect
@targeted(
@lifeloss(
@lifed(
add a special ability builder called dynamicability
it acts alot like a choose your own adventure book
dynamicability<! variable 1, variable 2, variable 3,variable 4!> optional ability targetting the original target.
variable list 1:
this is the primary amount source
source
mytgt
myself
myfoe
variable list 2:
this is the variable we're after, or the amount
power
toughness
manacost
colors
age
charge
oneonecounters
thatmuch
variable list 3:
this is the main effect
strike
draw
lifeloss
lifegain
pumppow
pumptough
pumpboth
deplete
countersoneone
variable list 4:
how it will do this effect to.
itself
eachother
targetcontroller
targetopponent
tosrc
srccontroller
srcopponent
the best way to explain its usage is to look at cards coded with this ability. or experiment with combinations.
new gameoption
First turn player:player, opponent, random
who takes the first turn
added poisoned status, tho not complete since MBS hasnt spoiled enough cards to see where this variable will be used.
taught ai how to counter spell
improved ai, it will now cast instants during interupts and during your turn.
previously ai treated instant cards the same as it treated sorceries, which was not fair to the ai.
im sure there is some messed items, but the rev directly before this one had formatting in the code that created hundreds of conflicts with this one, so i had to dig this info out of red and green sections.
cards and test are coming soon, i ask PLEASE do not alter these new additions until the test are commited.
im commiting without the test because instead of allowing me to proceed with my beta test period, there are some that wish to rush me into a commit. if you do not like this commit revert it, i absolutely on no grounds give permission to recommit afterwards. and i will not recommit if a revert is called.
This commit is contained in:
@@ -18,6 +18,7 @@ using std::queue;
|
|||||||
#define INFO_CREATURESTOUGHNESS 3
|
#define INFO_CREATURESTOUGHNESS 3
|
||||||
#define INFO_CREATURESATTACKINGPOWER 4
|
#define INFO_CREATURESATTACKINGPOWER 4
|
||||||
|
|
||||||
|
|
||||||
class AIStats;
|
class AIStats;
|
||||||
|
|
||||||
class AIAction
|
class AIAction
|
||||||
@@ -34,25 +35,22 @@ public:
|
|||||||
MTGCardInstance * click;
|
MTGCardInstance * click;
|
||||||
MTGCardInstance * target; // TODO Improve
|
MTGCardInstance * target; // TODO Improve
|
||||||
|
|
||||||
AIAction(MTGAbility * a, MTGCardInstance * c, MTGCardInstance * t = NULL) :
|
AIAction(MTGAbility * a, MTGCardInstance * c, MTGCardInstance * t = NULL)
|
||||||
efficiency(-1), ability(a), player(NULL), click(c), target(t)
|
: efficiency(-1), ability(a), player(NULL), click(c), target(t)
|
||||||
{
|
{
|
||||||
id = currentId++;
|
id = currentId++;
|
||||||
}
|
};
|
||||||
;
|
|
||||||
|
|
||||||
AIAction(MTGCardInstance * c, MTGCardInstance * t = NULL) :
|
AIAction(MTGCardInstance * c, MTGCardInstance * t = NULL)
|
||||||
efficiency(-1), ability(NULL), player(NULL), click(c), target(t)
|
: efficiency(-1), ability(NULL), player(NULL), click(c), target(t)
|
||||||
{
|
{
|
||||||
id = currentId++;
|
id = currentId++;
|
||||||
}
|
};
|
||||||
;
|
|
||||||
|
|
||||||
AIAction(Player * p) :
|
AIAction(Player * p)
|
||||||
efficiency(-1), ability(NULL), player(p), click(NULL), target(NULL)
|
: efficiency(-1), ability(NULL), player(p), click(NULL), target(NULL)
|
||||||
{
|
{
|
||||||
}
|
};
|
||||||
;
|
|
||||||
|
|
||||||
int getEfficiency();
|
int getEfficiency();
|
||||||
int Act();
|
int Act();
|
||||||
@@ -64,20 +62,18 @@ class CmpAbilities
|
|||||||
public:
|
public:
|
||||||
bool operator()(const AIAction& a1, const AIAction& a2) const
|
bool operator()(const AIAction& a1, const AIAction& a2) const
|
||||||
{
|
{
|
||||||
AIAction* a1Ptr = const_cast<AIAction*> (&a1);
|
AIAction* a1Ptr = const_cast<AIAction*>(&a1);
|
||||||
AIAction* a2Ptr = const_cast<AIAction*> (&a2);
|
AIAction* a2Ptr = const_cast<AIAction*>(&a2);
|
||||||
int e1 = a1Ptr->getEfficiency();
|
int e1 = a1Ptr->getEfficiency();
|
||||||
int e2 = a2Ptr->getEfficiency();
|
int e2 = a2Ptr->getEfficiency();
|
||||||
if (e1 == e2)
|
if (e1 == e2) return a1Ptr->id < a2Ptr->id;
|
||||||
return a1Ptr->id < a2Ptr->id;
|
|
||||||
return (e1 > e2);
|
return (e1 > e2);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<AIAction, int, CmpAbilities> RankingContainer;
|
typedef std::map<AIAction, int, CmpAbilities> RankingContainer;
|
||||||
|
|
||||||
class AIPlayer: public Player
|
class AIPlayer: public Player{
|
||||||
{
|
|
||||||
protected:
|
protected:
|
||||||
//Variables used by Test suite
|
//Variables used by Test suite
|
||||||
MTGCardInstance * nextCardToPlay;
|
MTGCardInstance * nextCardToPlay;
|
||||||
@@ -90,7 +86,7 @@ protected:
|
|||||||
int chooseBlockers();
|
int chooseBlockers();
|
||||||
int canFirstStrikeKill(MTGCardInstance * card, MTGCardInstance *ennemy);
|
int canFirstStrikeKill(MTGCardInstance * card, MTGCardInstance *ennemy);
|
||||||
int effectBadOrGood(MTGCardInstance * card, int mode = MODE_PUTINTOPLAY, TargetChooser * tc = NULL);
|
int effectBadOrGood(MTGCardInstance * card, int mode = MODE_PUTINTOPLAY, TargetChooser * tc = NULL);
|
||||||
int getCreaturesInfo(Player * player, int neededInfo = INFO_NBCREATURES, int untapMode = 0, int canAttack = 0);
|
int getCreaturesInfo(Player * player, int neededInfo = INFO_NBCREATURES , int untapMode = 0, int canAttack = 0);
|
||||||
AIStats * getStats();
|
AIStats * getStats();
|
||||||
|
|
||||||
// returns 1 if the AI algorithm supports a given cost (ex:simple mana cost), 0 otherwise (ex: cost involves Sacrificing a target)
|
// returns 1 if the AI algorithm supports a given cost (ex:simple mana cost), 0 otherwise (ex: cost involves Sacrificing a target)
|
||||||
@@ -101,29 +97,18 @@ public:
|
|||||||
int agressivity;
|
int agressivity;
|
||||||
bool Checked;
|
bool Checked;
|
||||||
bool forceBestAbilityUse;
|
bool forceBestAbilityUse;
|
||||||
void End()
|
void End(){};
|
||||||
{
|
virtual int displayStack() {return 0;};
|
||||||
}
|
|
||||||
;
|
|
||||||
virtual int displayStack()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
int receiveEvent(WEvent * event);
|
int receiveEvent(WEvent * event);
|
||||||
void Render();
|
void Render();
|
||||||
ManaCost * getPotentialMana(MTGCardInstance * card = NULL);
|
ManaCost * getPotentialMana(MTGCardInstance * card = NULL);
|
||||||
AIPlayer(MTGDeck * deck, string deckFile, string deckFileSmall);
|
AIPlayer(MTGDeck * deck, string deckFile, string deckFileSmall);
|
||||||
virtual ~AIPlayer();
|
virtual ~AIPlayer();
|
||||||
virtual MTGCardInstance * chooseCard(TargetChooser * tc, MTGCardInstance * source, int random = 0);
|
virtual MTGCardInstance * chooseCard(TargetChooser * tc, MTGCardInstance * source, int random = 0);
|
||||||
virtual int chooseTarget(TargetChooser * tc = NULL, Player * forceTarget = NULL);
|
virtual int chooseTarget(TargetChooser * tc = NULL, Player * forceTarget =NULL,MTGCardInstance * Choosencard = NULL);
|
||||||
virtual int Act(float dt);
|
virtual int Act(float dt);
|
||||||
virtual int affectCombatDamages(CombatStep);
|
virtual int affectCombatDamages(CombatStep);
|
||||||
int isAI()
|
int isAI(){return 1;};
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
int canHandleCost(MTGAbility * ability);
|
int canHandleCost(MTGAbility * ability);
|
||||||
int selectAbility();
|
int selectAbility();
|
||||||
int createAbilityTargets(MTGAbility * a, MTGCardInstance * c, RankingContainer& ranking);
|
int createAbilityTargets(MTGAbility * a, MTGCardInstance * c, RankingContainer& ranking);
|
||||||
@@ -132,24 +117,24 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class AIPlayerBaka: public AIPlayer
|
|
||||||
{
|
class AIPlayerBaka: public AIPlayer{
|
||||||
protected:
|
protected:
|
||||||
int oldGamePhase;
|
int oldGamePhase;
|
||||||
float timer;
|
float timer;
|
||||||
MTGCardInstance * FindCardToPlay(ManaCost * potentialMana, const char * type);
|
MTGCardInstance * FindCardToPlay(ManaCost * potentialMana, const char * type);
|
||||||
public:
|
public:
|
||||||
int deckId;
|
int deckId;
|
||||||
AIPlayerBaka(MTGDeck * deck, string deckFile, string deckfileSmall, string avatarFile);
|
AIPlayerBaka(MTGDeck * deck, string deckFile, string deckfileSmall, string avatarFile);
|
||||||
virtual int Act(float dt);
|
virtual int Act(float dt);
|
||||||
void initTimer();
|
void initTimer();
|
||||||
virtual int computeActions();
|
virtual int computeActions();
|
||||||
};
|
};
|
||||||
|
|
||||||
class AIPlayerFactory
|
class AIPlayerFactory{
|
||||||
{
|
public:
|
||||||
public:
|
AIPlayer * createAIPlayer(MTGAllCards * collection, Player * opponent, int deckid = 0);
|
||||||
AIPlayer * createAIPlayer(MTGAllCards * collection, Player * opponent, int deckid = 0);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+140
-164
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#define MAX_SPELL_TARGETS 10
|
#define MAX_SPELL_TARGETS 10
|
||||||
|
|
||||||
|
|
||||||
#define ACTION_SPELL 10
|
#define ACTION_SPELL 10
|
||||||
#define ACTION_DAMAGE 11
|
#define ACTION_DAMAGE 11
|
||||||
#define ACTION_DAMAGES 12
|
#define ACTION_DAMAGES 12
|
||||||
@@ -38,197 +39,172 @@ class DamageStack;
|
|||||||
class ManaCost;
|
class ManaCost;
|
||||||
class TargetChooser;
|
class TargetChooser;
|
||||||
|
|
||||||
|
|
||||||
#define ACTIONSTACK_STANDARD 0
|
#define ACTIONSTACK_STANDARD 0
|
||||||
#define ACTIONSTACK_TARGET 1
|
#define ACTIONSTACK_TARGET 1
|
||||||
|
|
||||||
class Interruptible: public PlayGuiObject, public Targetable
|
class Interruptible: public PlayGuiObject, public Targetable{
|
||||||
{
|
public:
|
||||||
public:
|
//TODO : remove these when they are back in PlayGuiObject
|
||||||
//TODO : remove these when they are back in PlayGuiObject
|
float x, y;
|
||||||
float x, y;
|
|
||||||
|
|
||||||
int state, display;
|
int state, display;
|
||||||
MTGCardInstance * source;
|
MTGCardInstance * source;
|
||||||
virtual void Entering()
|
virtual void Entering(){mHasFocus = true;};
|
||||||
{
|
virtual bool Leaving(JButton key){mHasFocus = false;return true;};
|
||||||
mHasFocus = true;
|
virtual bool ButtonPressed(){return true;};
|
||||||
}
|
virtual int resolve(){return 0;};
|
||||||
;
|
virtual void Render(){};
|
||||||
virtual bool Leaving(JButton key)
|
int typeAsTarget(){return TARGET_STACKACTION;};
|
||||||
{
|
Interruptible(bool hasFocus = false):PlayGuiObject(40,x,y,hasFocus){state=NOT_RESOLVED;display=0;source=NULL;};
|
||||||
mHasFocus = false;
|
virtual const string getDisplayName() const;
|
||||||
return true;
|
void Render(MTGCardInstance * source, JQuad * targetQuad, string alt1, string alt2, string action, bool bigQuad = false);
|
||||||
}
|
virtual int receiveEvent(WEvent * event) {return 0;};
|
||||||
;
|
|
||||||
virtual bool ButtonPressed()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
virtual int resolve()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
virtual void Render()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
;
|
|
||||||
int typeAsTarget()
|
|
||||||
{
|
|
||||||
return TARGET_STACKACTION;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
Interruptible(bool hasFocus = false) :
|
|
||||||
PlayGuiObject(40, x, y, hasFocus)
|
|
||||||
{
|
|
||||||
state = NOT_RESOLVED;
|
|
||||||
display = 0;
|
|
||||||
source = NULL;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
virtual const string getDisplayName() const;
|
|
||||||
void Render(MTGCardInstance * source, JQuad * targetQuad, string alt1, string alt2, string action, bool bigQuad = false);
|
|
||||||
virtual int receiveEvent(WEvent * event)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
#if defined (WIN32) || defined (LINUX) || defined (IOS)
|
#if defined (WIN32) || defined (LINUX) || defined (IOS)
|
||||||
virtual void Dump();
|
virtual void Dump();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float GetVerticalTextOffset() const;
|
float GetVerticalTextOffset() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NextGamePhase: public Interruptible
|
class NextGamePhase: public Interruptible {
|
||||||
{
|
public:
|
||||||
public:
|
int resolve();
|
||||||
int resolve();
|
bool extraDamagePhase();
|
||||||
bool extraDamagePhase();
|
void Render();
|
||||||
void Render();
|
virtual ostream& toString(ostream& out) const;
|
||||||
virtual ostream& toString(ostream& out) const;
|
virtual const string getDisplayName() const;
|
||||||
virtual const string getDisplayName() const;
|
NextGamePhase(int id);
|
||||||
NextGamePhase(int id);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Spell: public Interruptible
|
class Spell: public Interruptible {
|
||||||
{
|
protected:
|
||||||
protected:
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MTGGameZone * from;
|
MTGGameZone * from;
|
||||||
TargetChooser * tc;
|
TargetChooser * tc;
|
||||||
ManaCost * cost;
|
ManaCost * cost;
|
||||||
int payResult;
|
int payResult;
|
||||||
int computeX(MTGCardInstance * card);
|
int computeX(MTGCardInstance * card);
|
||||||
int computeXX(MTGCardInstance * card);
|
int computeXX(MTGCardInstance * card);
|
||||||
Spell(MTGCardInstance* _source);
|
Spell(MTGCardInstance* _source);
|
||||||
Spell(int id, MTGCardInstance* _source, TargetChooser *_tc, ManaCost * _cost, int payResult);
|
Spell(int id, MTGCardInstance* _source, TargetChooser *_tc, ManaCost * _cost, int payResult);
|
||||||
~Spell();
|
~Spell();
|
||||||
int resolve();
|
int resolve();
|
||||||
void Render();
|
void Render();
|
||||||
bool FullfilledAlternateCost(const int &costType);
|
bool FullfilledAlternateCost(const int &costType);
|
||||||
const string getDisplayName() const;
|
const string getDisplayName() const;
|
||||||
virtual ostream& toString(ostream& out) const;
|
virtual ostream& toString(ostream& out) const;
|
||||||
MTGCardInstance * getNextCardTarget(MTGCardInstance * previous = 0);
|
MTGCardInstance * getNextCardTarget(MTGCardInstance * previous = 0);
|
||||||
Player * getNextPlayerTarget(Player * previous = 0);
|
Player * getNextPlayerTarget(Player * previous = 0);
|
||||||
Damageable * getNextDamageableTarget(Damageable * previous = 0);
|
Damageable * getNextDamageableTarget(Damageable * previous = 0);
|
||||||
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 = 0, int type = -1);
|
Targetable * getNextTarget(Targetable * previous = 0, int type = -1);
|
||||||
int getNbTargets();
|
int getNbTargets();
|
||||||
};
|
};
|
||||||
|
|
||||||
class StackAbility: public Interruptible
|
class StackAbility: public Interruptible {
|
||||||
{
|
public:
|
||||||
public:
|
MTGAbility * ability;
|
||||||
MTGAbility * ability;
|
int resolve();
|
||||||
int resolve();
|
void Render();
|
||||||
void Render();
|
virtual ostream& toString(ostream& out) const;
|
||||||
virtual ostream& toString(ostream& out) const;
|
virtual const string getDisplayName() const;
|
||||||
virtual const string getDisplayName() const;
|
StackAbility(int id, MTGAbility * _ability);
|
||||||
StackAbility(int id, MTGAbility * _ability);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PutInGraveyard: public Interruptible
|
class PutInGraveyard: public Interruptible {
|
||||||
{
|
public:
|
||||||
public:
|
MTGCardInstance * card;
|
||||||
MTGCardInstance * card;
|
int removeFromGame;
|
||||||
int removeFromGame;
|
int resolve();
|
||||||
int resolve();
|
void Render();
|
||||||
void Render();
|
virtual ostream& toString(ostream& out) const;
|
||||||
virtual ostream& toString(ostream& out) const;
|
PutInGraveyard(int id, MTGCardInstance * _card);
|
||||||
PutInGraveyard(int id, MTGCardInstance * _card);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DrawAction: public Interruptible
|
|
||||||
{
|
class DrawAction: public Interruptible {
|
||||||
public:
|
public:
|
||||||
int nbcards;
|
int nbcards;
|
||||||
Player * player;
|
Player * player;
|
||||||
int resolve();
|
int resolve();
|
||||||
void Render();
|
void Render();
|
||||||
virtual ostream& toString(ostream& out) const;
|
virtual ostream& toString(ostream& out) const;
|
||||||
DrawAction(int id, Player * _player, int _nbcards);
|
DrawAction(int id, Player * _player, int _nbcards);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ActionStack: public GuiLayer
|
class LifeAction: public Interruptible {
|
||||||
{
|
public:
|
||||||
protected:
|
int amount;
|
||||||
JQuad * pspIcons[8];
|
Damageable * target;
|
||||||
GameObserver* game;
|
int resolve();
|
||||||
int interruptDecision[2];
|
void Render();
|
||||||
float timer;
|
virtual ostream& toString(ostream& out) const;
|
||||||
int currentState;
|
LifeAction(int id, Damageable * _target, int amount);
|
||||||
int mode;
|
};
|
||||||
int checked;
|
|
||||||
|
|
||||||
public:
|
class ActionStack :public GuiLayer{
|
||||||
|
protected:
|
||||||
|
JQuad * pspIcons[8];
|
||||||
|
GameObserver* game;
|
||||||
|
int interruptDecision[2];
|
||||||
|
float timer;
|
||||||
|
int currentState;
|
||||||
|
int mode;
|
||||||
|
int checked;
|
||||||
|
|
||||||
enum
|
public:
|
||||||
{
|
|
||||||
NOT_DECIDED = 0,
|
|
||||||
INTERRUPT = -1,
|
|
||||||
DONT_INTERRUPT = 1,
|
|
||||||
DONT_INTERRUPT_ALL = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
int setIsInterrupting(Player * player);
|
enum
|
||||||
int count(int type = 0, int state = 0, int display = -1);
|
{
|
||||||
Interruptible * getPrevious(Interruptible * next, int type = 0, int state = 0, int display = -1);
|
NOT_DECIDED = 0,
|
||||||
int getPreviousIndex(Interruptible * next, int type = 0, int state = 0, int display = -1);
|
INTERRUPT = -1,
|
||||||
Interruptible * getNext(Interruptible * previous, int type = 0, int state = 0, int display = -1);
|
DONT_INTERRUPT = 1,
|
||||||
int getNextIndex(Interruptible * previous, int type = 0, int state = 0, int display = -1);
|
DONT_INTERRUPT_ALL = 2,
|
||||||
void Fizzle(Interruptible * action);
|
};
|
||||||
Interruptible * getAt(int id);
|
|
||||||
void cancelInterruptOffer(int cancelMode = 1);
|
int setIsInterrupting(Player * player);
|
||||||
void endOfInterruption();
|
int count( int type = 0 , int state = 0 , int display = -1);
|
||||||
Interruptible * getLatest(int state);
|
Interruptible * getPrevious(Interruptible * next, int type = 0, int state = 0 , int display = -1);
|
||||||
Player * askIfWishesToInterrupt;
|
int getPreviousIndex(Interruptible * next, int type = 0, int state = 0 , int display = -1);
|
||||||
int garbageCollect();
|
Interruptible * getNext(Interruptible * previous, int type = 0, int state = 0 , int display = -1);
|
||||||
int addAction(Interruptible * interruptible);
|
int getNextIndex(Interruptible * previous, int type = 0, int state = 0 , int display = -1);
|
||||||
Spell * addSpell(MTGCardInstance* card, TargetChooser * tc, ManaCost * mana, int payResult, int storm);
|
void Fizzle(Interruptible * action);
|
||||||
int AddNextGamePhase();
|
Interruptible * getAt(int id);
|
||||||
int AddNextCombatStep();
|
void cancelInterruptOffer(int cancelMode = 1);
|
||||||
int addPutInGraveyard(MTGCardInstance * card);
|
void endOfInterruption();
|
||||||
int addDraw(Player * player, int nbcards = 1);
|
Interruptible * getLatest(int state);
|
||||||
int addDamage(MTGCardInstance * _source, Damageable * target, int _damage);
|
Player * askIfWishesToInterrupt;
|
||||||
int addAbility(MTGAbility * ability);
|
int garbageCollect();
|
||||||
void Update(float dt);
|
int addAction(Interruptible * interruptible);
|
||||||
bool CheckUserInput(JButton key);
|
Spell * addSpell(MTGCardInstance* card, TargetChooser * tc, ManaCost * mana, int payResult, int storm);
|
||||||
virtual void Render();
|
int AddNextGamePhase();
|
||||||
ActionStack(GameObserver* game);
|
int AddNextCombatStep();
|
||||||
int resolve();
|
int addPutInGraveyard(MTGCardInstance * card);
|
||||||
int has(Interruptible * action);
|
int addDraw(Player * player, int nbcards = 1);
|
||||||
int has(MTGAbility * ability);
|
int addLife(Damageable * _target,int amount = 0);
|
||||||
int receiveEventPlus(WEvent * event);
|
int addDamage(MTGCardInstance * _source, Damageable * target, int _damage);
|
||||||
|
int addAbility(MTGAbility * ability);
|
||||||
|
void Update(float dt);
|
||||||
|
bool CheckUserInput(JButton key);
|
||||||
|
virtual void Render();
|
||||||
|
ActionStack(GameObserver* game);
|
||||||
|
int resolve();
|
||||||
|
int has(Interruptible * action);
|
||||||
|
int has(MTGAbility * ability);
|
||||||
|
int receiveEventPlus(WEvent * event);
|
||||||
#if defined (WIN32) || defined (LINUX) || defined (IOS)
|
#if defined (WIN32) || defined (LINUX) || defined (IOS)
|
||||||
void Dump();
|
void Dump();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
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_
|
#ifndef _CARDDESCRIPTOR_H_
|
||||||
#define _CARDDESCRIPTOR_H_
|
#define _CARDDESCRIPTOR_H_
|
||||||
@@ -13,42 +13,48 @@
|
|||||||
#define CD_AND 2
|
#define CD_AND 2
|
||||||
|
|
||||||
enum ENUM_COMPARISON_MODES
|
enum ENUM_COMPARISON_MODES
|
||||||
{
|
{
|
||||||
COMPARISON_NONE = 0, // Needs to remain 0 for quick if(comparison_mode) checks
|
COMPARISON_NONE = 0, // Needs to remain 0 for quick if(comparison_mode) checks
|
||||||
COMPARISON_AT_MOST,
|
COMPARISON_AT_MOST,
|
||||||
COMPARISON_AT_LEAST,
|
COMPARISON_AT_LEAST,
|
||||||
COMPARISON_EQUAL,
|
COMPARISON_EQUAL,
|
||||||
COMPARISON_GREATER,
|
COMPARISON_GREATER,
|
||||||
COMPARISON_LESS,
|
COMPARISON_LESS,
|
||||||
COMPARISON_UNEQUAL
|
COMPARISON_UNEQUAL
|
||||||
};
|
};
|
||||||
|
|
||||||
class CardDescriptor: public MTGCardInstance
|
class CardDescriptor: public MTGCardInstance{
|
||||||
{
|
protected:
|
||||||
protected:
|
MTGCardInstance * match_or(MTGCardInstance * card);
|
||||||
MTGCardInstance * match_or(MTGCardInstance * card);
|
MTGCardInstance * match_and(MTGCardInstance * card);
|
||||||
MTGCardInstance * match_and(MTGCardInstance * card);
|
bool valueInRange(int comparisonMode, int value, int criterion);
|
||||||
bool valueInRange(int comparisonMode, int value, int criterion);
|
public:
|
||||||
public:
|
int mode;
|
||||||
int mode;
|
int powerComparisonMode;
|
||||||
int powerComparisonMode;
|
int toughnessComparisonMode;
|
||||||
int toughnessComparisonMode;
|
int manacostComparisonMode;
|
||||||
int manacostComparisonMode;
|
int counterComparisonMode;
|
||||||
int counterComparisonMode;
|
int convertedManacost; // might fit better into MTGCardInstance?
|
||||||
int convertedManacost; // might fit better into MTGCardInstance?
|
int anyCounter;
|
||||||
int anyCounter;
|
int init();
|
||||||
int init();
|
CardDescriptor();
|
||||||
CardDescriptor();
|
void unsecureSetTapped(int i);
|
||||||
void unsecureSetTapped(int i);
|
void unsecuresetfresh(int k);
|
||||||
void unsecuresetfresh(int k);
|
void setisMultiColored(int w);
|
||||||
void setNegativeSubtype(string value);
|
void setisBlackAndWhite(int w);
|
||||||
int counterPower;
|
void setisRedAndBlue(int w);
|
||||||
int counterToughness;
|
void setisBlackAndGreen(int w);
|
||||||
int counterNB;
|
void setisBlueAndGreen(int w);
|
||||||
string counterName;
|
void setisRedAndWhite(int w);
|
||||||
MTGCardInstance * match(MTGCardInstance * card);
|
|
||||||
MTGCardInstance * match(MTGGameZone * zone);
|
void setNegativeSubtype( string value);
|
||||||
MTGCardInstance * nextmatch(MTGGameZone * zone, MTGCardInstance * previous);
|
int counterPower;
|
||||||
|
int counterToughness;
|
||||||
|
int counterNB;
|
||||||
|
string counterName;
|
||||||
|
MTGCardInstance * match(MTGCardInstance * card);
|
||||||
|
MTGCardInstance * match(MTGGameZone * zone);
|
||||||
|
MTGCardInstance * nextmatch(MTGGameZone * zone, MTGCardInstance * previous);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifndef _CARDPRIMITIVE_H_
|
#ifndef _CARDPRIMITIVE_H_
|
||||||
#define _CARDPRIMITIVE_H_
|
#define _CARDPRIMITIVE_H_
|
||||||
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
@@ -9,72 +10,144 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
class CardPrimitive
|
class CardPrimitive {
|
||||||
{
|
protected:
|
||||||
protected:
|
vector<string> ftdText;
|
||||||
vector<string> ftdText;
|
string lcname;
|
||||||
string lcname;
|
ManaCost manaCost;
|
||||||
ManaCost manaCost;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
string text;
|
enum {
|
||||||
string name;
|
NO_RESTRICTION = 0,
|
||||||
int init();
|
PLAYER_TURN_ONLY = 1,
|
||||||
|
AS_SORCERY = 2,
|
||||||
|
MY_BEFORE_BEGIN = 3,
|
||||||
|
MY_UNTAP = 4,
|
||||||
|
MY_UPKEEP = 5,
|
||||||
|
MY_DRAW = 6,
|
||||||
|
MY_FIRSTMAIN = 7,
|
||||||
|
MY_COMBATBEGIN = 8,
|
||||||
|
MY_COMBATATTACKERS = 9,
|
||||||
|
MY_COMBATBLOCKERS = 10,
|
||||||
|
MY_COMBATDAMAGE = 11,
|
||||||
|
MY_COMBATEND = 12,
|
||||||
|
MY_SECONDMAIN = 13,
|
||||||
|
MY_ENDOFTURN = 14,
|
||||||
|
MY_EOT = 15,
|
||||||
|
MY_CLEANUP = 16,
|
||||||
|
MY_AFTER_EOT = 17,
|
||||||
|
|
||||||
int colors[Constants::MTG_NB_COLORS];
|
OPPONENT_BEFORE_BEGIN = 23,
|
||||||
map<int, int> basicAbilities;
|
OPPONENT_UNTAP = 24,
|
||||||
map<string, string> magicTexts;
|
OPPONENT_UPKEEP = 25,
|
||||||
string magicText;
|
OPPONENT_DRAW = 26,
|
||||||
int alias;
|
OPPONENT_FIRSTMAIN = 27,
|
||||||
string spellTargetType;
|
OPPONENT_COMBATBEGIN = 28,
|
||||||
int power;
|
OPPONENT_COMBATATTACKERS = 29,
|
||||||
int toughness;
|
OPPONENT_COMBATBLOCKERS = 30,
|
||||||
vector<int> types;
|
OPPONENT_COMBATDAMAGE = 31,
|
||||||
CardPrimitive();
|
OPPONENT_COMBATEND = 32,
|
||||||
CardPrimitive(CardPrimitive * source);
|
OPPONENT_SECONDMAIN = 33,
|
||||||
|
OPPONENT_ENDOFTURN = 34,
|
||||||
|
OPPONENT_EOT = 35,
|
||||||
|
OPPONENT_CLEANUP = 36,
|
||||||
|
OPPONENT_AFTER_EOT = 37,
|
||||||
|
|
||||||
void setColor(int _color, int removeAllOthers = 0);
|
BEFORE_BEGIN = 43,
|
||||||
void setColor(string _color, int removeAllOthers = 0);
|
UNTAP = 44,
|
||||||
void removeColor(int color);
|
UPKEEP = 45,
|
||||||
int getColor();
|
DRAW = 46,
|
||||||
int hasColor(int _color);
|
FIRSTMAIN = 47,
|
||||||
int countColors();
|
COMBATBEGIN = 48,
|
||||||
|
COMBATATTACKERS = 49,
|
||||||
|
COMBATBLOCKERS = 50,
|
||||||
|
COMBATDAMAGE = 51,
|
||||||
|
COMBATEND = 52,
|
||||||
|
SECONDMAIN = 53,
|
||||||
|
ENDOFTURN = 54,
|
||||||
|
EOT = 55,
|
||||||
|
CLEANUP = 56,
|
||||||
|
AFTER_EOT = 57,
|
||||||
|
|
||||||
int has(int ability);
|
VAMPIRES = 60,
|
||||||
|
LESS_CREATURES = 61,
|
||||||
|
SNOW_LAND_INPLAY =62,
|
||||||
|
CASTED_A_SPELL = 63,
|
||||||
|
ONE_OF_AKIND = 64,
|
||||||
|
FOURTHTURN = 65,
|
||||||
|
BEFORECOMBATDAMAGE = 66,
|
||||||
|
AFTERCOMBAT = 67,
|
||||||
|
DURINGCOMBAT = 68,
|
||||||
|
OPPONENT_TURN_ONLY = 69,
|
||||||
|
|
||||||
void setText(const string& value);
|
};
|
||||||
const char * getText();
|
string text;
|
||||||
|
string name;
|
||||||
|
int init();
|
||||||
|
|
||||||
void addMagicText(string value);
|
int colors[Constants::MTG_NB_COLORS];
|
||||||
void addMagicText(string value, string zone);
|
map<int,int> basicAbilities;
|
||||||
|
map<string,string> magicTexts;
|
||||||
|
string magicText;
|
||||||
|
int alias;
|
||||||
|
string spellTargetType;
|
||||||
|
int power;
|
||||||
|
int toughness;
|
||||||
|
bool hasRestriction;
|
||||||
|
int restriction;
|
||||||
|
string otherrestriction;
|
||||||
|
|
||||||
void setName(const string& value);
|
vector<int>types;
|
||||||
const string& getName() const;
|
CardPrimitive();
|
||||||
const string& getLCName() const;
|
CardPrimitive(CardPrimitive * source);
|
||||||
|
|
||||||
void addType(char * type_text);
|
void setColor(int _color, int removeAllOthers = 0);
|
||||||
void addType(int id);
|
void setColor(string _color, int removeAllOthers = 0);
|
||||||
void setType(const string& type_text);
|
void removeColor(int color);
|
||||||
void setSubtype(const string& value);
|
int getColor();
|
||||||
int removeType(string value, int removeAll = 0);
|
int hasColor(int _color);
|
||||||
int removeType(int value, int removeAll = 0);
|
int countColors();
|
||||||
bool hasSubtype(int _subtype);
|
|
||||||
bool hasSubtype(const char * _subtype);
|
|
||||||
bool hasSubtype(string _subtype);
|
|
||||||
bool hasType(int _type);
|
|
||||||
bool hasType(const char * type);
|
|
||||||
|
|
||||||
void setManaCost(string value);
|
int has(int ability);
|
||||||
ManaCost * getManaCost();
|
|
||||||
bool isCreature();
|
|
||||||
bool isLand();
|
|
||||||
bool isSpell();
|
|
||||||
|
|
||||||
void setPower(int _power);
|
void setText(const string& value);
|
||||||
int getPower();
|
const char * getText();
|
||||||
void setToughness(int _toughness);
|
|
||||||
int getToughness();
|
void addMagicText(string value);
|
||||||
const vector<string>& formattedText();
|
void addMagicText(string value, string zone);
|
||||||
|
|
||||||
|
void setName(const string& value);
|
||||||
|
const string& getName() const;
|
||||||
|
const string& getLCName() const;
|
||||||
|
|
||||||
|
void addType(char * type_text);
|
||||||
|
void addType(int id);
|
||||||
|
void setType(const string& type_text);
|
||||||
|
void setSubtype(const string& value);
|
||||||
|
int removeType(string value, int removeAll = 0);
|
||||||
|
int removeType(int value, int removeAll = 0);
|
||||||
|
bool hasSubtype(int _subtype);
|
||||||
|
bool hasSubtype(const char * _subtype);
|
||||||
|
bool hasSubtype(string _subtype);
|
||||||
|
bool hasType(int _type);
|
||||||
|
bool hasType(const char * type);
|
||||||
|
|
||||||
|
void setManaCost(string value);
|
||||||
|
ManaCost * getManaCost();
|
||||||
|
bool isCreature();
|
||||||
|
bool isLand();
|
||||||
|
bool isSpell();
|
||||||
|
|
||||||
|
void setPower(int _power);
|
||||||
|
int getPower();
|
||||||
|
void setToughness(int _toughness);
|
||||||
|
int getToughness();
|
||||||
|
void setRestrictions(int _restriction);
|
||||||
|
int getRestrictions();
|
||||||
|
void setOtherRestrictions(string _restriction);
|
||||||
|
void getOtherRestrictions();
|
||||||
|
const vector<string>& formattedText();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -17,77 +17,51 @@ class GameObserver;
|
|||||||
#define DAMAGE_COMBAT 1
|
#define DAMAGE_COMBAT 1
|
||||||
#define DAMAGE_OTHER 2
|
#define DAMAGE_OTHER 2
|
||||||
|
|
||||||
class Damageable: public Targetable
|
class Damageable:public Targetable {
|
||||||
{
|
|
||||||
protected:
|
protected:
|
||||||
public:
|
public:
|
||||||
int life;
|
int life;
|
||||||
int poisonCount;
|
int poisonCount;
|
||||||
int damageCount;
|
int damageCount;
|
||||||
int preventable;
|
int preventable;
|
||||||
|
int thatmuch;
|
||||||
|
int lifeLostThisTurn;
|
||||||
int type_as_damageable;
|
int type_as_damageable;
|
||||||
Damageable(int _life)
|
Damageable(int _life){life=_life;lifeLostThisTurn = 0;};
|
||||||
{
|
int getLife(){return life;};
|
||||||
life = _life;
|
virtual int dealDamage(int damage){life-=damage;return life;};
|
||||||
}
|
virtual int afterDamage(){return 0;}
|
||||||
;
|
virtual int poisoned(){return 0;}
|
||||||
int getLife()
|
virtual int prevented(){return 0;}
|
||||||
{
|
virtual JQuad * getIcon(){return NULL;};
|
||||||
return life;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
virtual int dealDamage(int damage)
|
|
||||||
{
|
|
||||||
life -= damage;
|
|
||||||
return life;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
virtual int afterDamage()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
virtual int poisoned()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
virtual int prevented()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
virtual JQuad * getIcon()
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Damage: public Interruptible
|
class Damage: public Interruptible {
|
||||||
{
|
protected:
|
||||||
protected:
|
void init(MTGCardInstance * source, Damageable * target, int damage, int typeOfDamage);
|
||||||
void init(MTGCardInstance * source, Damageable * target, int damage, int typeOfDamage);
|
public:
|
||||||
public:
|
Damageable * target;
|
||||||
Damageable * target;
|
int typeOfDamage;
|
||||||
int typeOfDamage;
|
int damage;
|
||||||
int damage;
|
void Render();
|
||||||
void Render();
|
Damage(MTGCardInstance* source, Damageable * target);
|
||||||
Damage(MTGCardInstance* source, Damageable * target);
|
Damage(MTGCardInstance* source, Damageable * target, int damage, int typeOfDamage = DAMAGE_OTHER);
|
||||||
Damage(MTGCardInstance* source, Damageable * target, int damage, int typeOfDamage = DAMAGE_OTHER);
|
int resolve();
|
||||||
int resolve();
|
virtual ostream& toString(ostream& out) const;
|
||||||
virtual ostream& toString(ostream& out) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DamageStack: public GuiLayer, public Interruptible
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
int currentState;
|
|
||||||
GameObserver* game;
|
|
||||||
|
|
||||||
public:
|
class DamageStack : public GuiLayer, public Interruptible{
|
||||||
int receiveEvent(WEvent * event);
|
protected:
|
||||||
int resolve();
|
int currentState;
|
||||||
void Render();
|
GameObserver* game;
|
||||||
virtual ostream& toString(ostream& out) const;
|
|
||||||
DamageStack();
|
public:
|
||||||
|
int receiveEvent(WEvent * event);
|
||||||
|
int resolve();
|
||||||
|
void Render();
|
||||||
|
virtual ostream& toString(ostream& out) const;
|
||||||
|
DamageStack();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -9,163 +9,145 @@ class TargetChooser;
|
|||||||
class MTGCardInstance;
|
class MTGCardInstance;
|
||||||
class MTGAbility;
|
class MTGAbility;
|
||||||
|
|
||||||
class ExtraCost
|
class ExtraCost{
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
TargetChooser * tc;
|
TargetChooser * tc;
|
||||||
MTGCardInstance * source;
|
MTGCardInstance * source;
|
||||||
MTGCardInstance * target;
|
MTGCardInstance * target;
|
||||||
std::string mCostRenderString;
|
MTGCardInstance * targets[20];
|
||||||
|
std::string mCostRenderString;
|
||||||
|
|
||||||
ExtraCost(const std::string& inCostRenderString, TargetChooser *_tc = NULL);
|
ExtraCost(const std::string& inCostRenderString, TargetChooser *_tc = NULL);
|
||||||
virtual ~ExtraCost();
|
virtual ~ExtraCost();
|
||||||
virtual int setPayment(MTGCardInstance * card);
|
virtual int setPayment(MTGCardInstance * card);
|
||||||
virtual int isPaymentSet()
|
virtual int isPaymentSet() { return (target != NULL && targets != NULL); }
|
||||||
{
|
virtual int canPay() { return 1; }
|
||||||
return (target != NULL);
|
virtual int doPay() = 0;
|
||||||
}
|
virtual void Render();
|
||||||
virtual int canPay()
|
virtual int setSource(MTGCardInstance * _source);
|
||||||
{
|
virtual ExtraCost* clone() const = 0;
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
virtual int doPay() = 0;
|
|
||||||
virtual void Render();
|
|
||||||
virtual int setSource(MTGCardInstance * _source);
|
|
||||||
virtual ExtraCost* clone() const = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ExtraCosts
|
class ExtraCosts{
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
vector<ExtraCost *> costs;
|
vector<ExtraCost *>costs;
|
||||||
MTGCardInstance * source;
|
MTGCardInstance * source;
|
||||||
MTGAbility * action;
|
MTGAbility * action;
|
||||||
ExtraCosts();
|
ExtraCosts();
|
||||||
~ExtraCosts();
|
~ExtraCosts();
|
||||||
void Render();
|
void Render();
|
||||||
int tryToSetPayment(MTGCardInstance * card);
|
int tryToSetPayment(MTGCardInstance * card);
|
||||||
int isPaymentSet();
|
int isPaymentSet();
|
||||||
int canPay();
|
int canPay();
|
||||||
int doPay();
|
int doPay();
|
||||||
int reset();
|
int reset();
|
||||||
int setAction(MTGAbility * _action, MTGCardInstance * _source);
|
int setAction(MTGAbility * _action, MTGCardInstance * _source);
|
||||||
void Dump();
|
void Dump();
|
||||||
ExtraCosts * clone() const;
|
ExtraCosts * clone() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SacrificeCost: public ExtraCost
|
class SacrificeCost: public ExtraCost{
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
SacrificeCost(TargetChooser *_tc = NULL);
|
SacrificeCost(TargetChooser *_tc = NULL);
|
||||||
virtual int doPay();
|
virtual int doPay();
|
||||||
virtual SacrificeCost * clone() const;
|
virtual SacrificeCost * clone() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//life cost
|
//life cost
|
||||||
class LifeCost: public ExtraCost
|
class LifeCost: public ExtraCost{
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
LifeCost(TargetChooser *_tc = NULL);
|
LifeCost(TargetChooser *_tc = NULL);
|
||||||
|
|
||||||
virtual int doPay();
|
virtual int doPay();
|
||||||
virtual LifeCost * clone() const;
|
virtual LifeCost * clone() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//Discard a random card cost
|
//Discard a random card cost
|
||||||
class DiscardRandomCost: public ExtraCost
|
class DiscardRandomCost: public ExtraCost{
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
DiscardRandomCost(TargetChooser *_tc = NULL);
|
DiscardRandomCost(TargetChooser *_tc = NULL);
|
||||||
virtual int canPay();
|
virtual int canPay();
|
||||||
virtual int doPay();
|
virtual int doPay();
|
||||||
virtual DiscardRandomCost * clone() const;
|
virtual DiscardRandomCost * clone() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//a choosen discard
|
//a choosen discard
|
||||||
class DiscardCost: public ExtraCost
|
class DiscardCost: public ExtraCost{
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
DiscardCost(TargetChooser *_tc = NULL);
|
DiscardCost(TargetChooser *_tc = NULL);
|
||||||
virtual int doPay();
|
virtual int doPay();
|
||||||
virtual DiscardCost * clone() const;
|
virtual DiscardCost * clone() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//tolibrary cost
|
//tolibrary cost
|
||||||
class ToLibraryCost: public ExtraCost
|
class ToLibraryCost: public ExtraCost{
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
ToLibraryCost(TargetChooser *_tc = NULL);
|
ToLibraryCost(TargetChooser *_tc = NULL);
|
||||||
virtual int doPay();
|
virtual int doPay();
|
||||||
virtual ToLibraryCost * clone() const;
|
virtual ToLibraryCost * clone() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//Millyourself cost
|
//Millyourself cost
|
||||||
class MillCost: public ExtraCost
|
class MillCost: public ExtraCost{
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
MillCost(TargetChooser *_tc = NULL);
|
MillCost(TargetChooser *_tc = NULL);
|
||||||
virtual int canPay();
|
virtual int canPay();
|
||||||
virtual int doPay();
|
virtual int doPay();
|
||||||
virtual MillCost * clone() const;
|
virtual MillCost * clone() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//Mill to exile yourself cost
|
//Mill to exile yourself cost
|
||||||
class MillExileCost: public MillCost
|
class MillExileCost: public MillCost{
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
MillExileCost(TargetChooser *_tc = NULL);
|
MillExileCost(TargetChooser *_tc = NULL);
|
||||||
virtual int doPay();
|
virtual int doPay();
|
||||||
};
|
};
|
||||||
|
|
||||||
//tap other cost
|
//tap other cost
|
||||||
class TapTargetCost: public ExtraCost
|
class TapTargetCost: public ExtraCost{
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
TapTargetCost(TargetChooser *_tc = NULL);
|
TapTargetCost(TargetChooser *_tc = NULL);
|
||||||
|
virtual int isPaymentSet();
|
||||||
virtual int doPay();
|
virtual int doPay();
|
||||||
virtual TapTargetCost * clone() const;
|
virtual TapTargetCost * clone() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//exile as cost
|
//exile as cost
|
||||||
class ExileTargetCost: public ExtraCost
|
class ExileTargetCost: public ExtraCost{
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
ExileTargetCost(TargetChooser *_tc = NULL);
|
ExileTargetCost(TargetChooser *_tc = NULL);
|
||||||
virtual int doPay();
|
virtual int doPay();
|
||||||
virtual ExileTargetCost * clone() const;
|
virtual ExileTargetCost * clone() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//bounce cost
|
//bounce cost
|
||||||
class BounceTargetCost: public ExtraCost
|
class BounceTargetCost: public ExtraCost{
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
BounceTargetCost(TargetChooser *_tc = NULL);
|
BounceTargetCost(TargetChooser *_tc = NULL);
|
||||||
virtual int doPay();
|
virtual int doPay();
|
||||||
virtual BounceTargetCost * clone() const;
|
virtual BounceTargetCost * clone() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//bounce cost
|
//bounce cost
|
||||||
class Ninja: public ExtraCost
|
class Ninja: public ExtraCost{
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
Ninja(TargetChooser *_tc = NULL);
|
Ninja(TargetChooser *_tc = NULL);
|
||||||
virtual int isPaymentSet();
|
virtual int isPaymentSet();
|
||||||
virtual int doPay();
|
virtual int doPay();
|
||||||
virtual Ninja * clone() const;
|
virtual Ninja * clone() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CounterCost: public ExtraCost
|
class CounterCost: public ExtraCost{
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
Counter * counter;
|
Counter * counter;
|
||||||
int hasCounters;
|
int hasCounters;
|
||||||
CounterCost(Counter * _counter, TargetChooser *_tc = NULL);
|
CounterCost(Counter * _counter,TargetChooser *_tc = NULL);
|
||||||
~CounterCost();
|
~CounterCost();
|
||||||
virtual int setPayment(MTGCardInstance * card);
|
virtual int setPayment(MTGCardInstance * card);
|
||||||
virtual int isPaymentSet();
|
virtual int isPaymentSet();
|
||||||
virtual int canPay();
|
virtual int canPay();
|
||||||
virtual int doPay();
|
virtual int doPay();
|
||||||
virtual CounterCost * clone() const;
|
virtual CounterCost * clone() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -22,70 +22,71 @@ class TargetChooser;
|
|||||||
class Rules;
|
class Rules;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
class GameObserver
|
class GameObserver{
|
||||||
{
|
protected:
|
||||||
protected:
|
static GameObserver * mInstance;
|
||||||
static GameObserver * mInstance;
|
MTGCardInstance * cardWaitingForTargets;
|
||||||
MTGCardInstance * cardWaitingForTargets;
|
queue<WEvent *> eventsQueue;
|
||||||
queue<WEvent *> eventsQueue;
|
|
||||||
|
|
||||||
int nbPlayers;
|
int nbPlayers;
|
||||||
int untap(MTGCardInstance * card);
|
int untap(MTGCardInstance * card);
|
||||||
bool WaitForExtraPayment(MTGCardInstance* card);
|
bool WaitForExtraPayment(MTGCardInstance* card);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int currentPlayerId;
|
int currentPlayerId;
|
||||||
CombatStep combatStep;
|
CombatStep combatStep;
|
||||||
int turn;
|
int turn;
|
||||||
int forceShuffleLibraries();
|
int forceShuffleLibraries();
|
||||||
int targetListIsSet(MTGCardInstance * card);
|
int targetListIsSet(MTGCardInstance * card);
|
||||||
PhaseRing * phaseRing;
|
PhaseRing * phaseRing;
|
||||||
int cancelCurrentAction();
|
int cancelCurrentAction();
|
||||||
int currentGamePhase;
|
int currentGamePhase;
|
||||||
ExtraCosts * mExtraPayment;
|
ExtraCosts * mExtraPayment;
|
||||||
int oldGamePhase;
|
int oldGamePhase;
|
||||||
TargetChooser * targetChooser;
|
TargetChooser * targetChooser;
|
||||||
DuelLayers * mLayers;
|
DuelLayers * mLayers;
|
||||||
ReplacementEffects *replacementEffects;
|
ReplacementEffects *replacementEffects;
|
||||||
Player * gameOver;
|
Player * gameOver;
|
||||||
Player * players[2]; //created outside
|
Player * players[2]; //created outside
|
||||||
time_t startedAt;
|
time_t startedAt;
|
||||||
Rules * mRules;
|
Rules * mRules;
|
||||||
|
|
||||||
TargetChooser * getCurrentTargetChooser();
|
TargetChooser * getCurrentTargetChooser();
|
||||||
void stackObjectClicked(Interruptible * action);
|
void stackObjectClicked(Interruptible * action);
|
||||||
|
|
||||||
int cardClick(MTGCardInstance * card, Targetable * _object = NULL);
|
int cardClick(MTGCardInstance * card,Targetable * _object = NULL );
|
||||||
int getCurrentGamePhase();
|
int getCurrentGamePhase();
|
||||||
void nextCombatStep();
|
void nextCombatStep();
|
||||||
void userRequestNextGamePhase();
|
void userRequestNextGamePhase();
|
||||||
void nextGamePhase();
|
void nextGamePhase();
|
||||||
void cleanupPhase();
|
void cleanupPhase();
|
||||||
void nextPlayer();
|
void nextPlayer();
|
||||||
static void Init(Player * _players[], int _nbplayers);
|
static void Init(Player * _players[], int _nbplayers);
|
||||||
static GameObserver * GetInstance();
|
static GameObserver * GetInstance();
|
||||||
static void EndInstance();
|
static void EndInstance();
|
||||||
Player * currentPlayer;
|
Player * currentPlayer;
|
||||||
Player * currentActionPlayer;
|
Player * currentActionPlayer;
|
||||||
Player * isInterrupting;
|
Player * isInterrupting;
|
||||||
Player * opponent();
|
Player * opponent();
|
||||||
Player * currentlyActing();
|
Player * currentlyActing();
|
||||||
GameObserver(Player * _players[], int _nbplayers);
|
GameObserver(Player * _players[], int _nbplayers);
|
||||||
~GameObserver();
|
~GameObserver();
|
||||||
void gameStateBasedEffects();
|
void gameStateBasedEffects();
|
||||||
void eventOccured();
|
void enchantmentStatus();
|
||||||
void addObserver(MTGAbility * observer);
|
void eventOccured();
|
||||||
void removeObserver(ActionElement * observer);
|
void addObserver(MTGAbility * observer);
|
||||||
void startGame(Rules * rules);
|
void removeObserver(ActionElement * observer);
|
||||||
void untapPhase();
|
void startGame(Rules * rules);
|
||||||
void draw();
|
void untapPhase();
|
||||||
int isInPlay(MTGCardInstance * card);
|
void draw();
|
||||||
|
int isInPlay(MTGCardInstance * card);
|
||||||
|
int isInGrave(MTGCardInstance * card);
|
||||||
|
int isInExile(MTGCardInstance * card);
|
||||||
|
void Update(float dt);
|
||||||
|
void Render();
|
||||||
|
void ButtonPressed(PlayGuiObject*);
|
||||||
|
|
||||||
void Update(float dt);
|
int receiveEvent(WEvent * event);
|
||||||
void Render();
|
|
||||||
void ButtonPressed(PlayGuiObject*);
|
|
||||||
|
|
||||||
int receiveEvent(WEvent * event);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+200
-279
@@ -23,339 +23,260 @@ class WStyle;
|
|||||||
class StyleManager;
|
class StyleManager;
|
||||||
class Player;
|
class Player;
|
||||||
|
|
||||||
class Options
|
class Options {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
friend class GameSettings;
|
friend class GameSettings;
|
||||||
enum
|
enum {
|
||||||
{
|
//Global settings
|
||||||
//Global settings
|
ACTIVE_PROFILE,
|
||||||
ACTIVE_PROFILE,
|
LANG,
|
||||||
LANG,
|
LAST_GLOBAL = LANG, //This must be the value above, to keep ordering.
|
||||||
LAST_GLOBAL = LANG, //This must be the value above, to keep ordering.
|
//Values /must/ match ordering in optionNames, or everything loads wrong.
|
||||||
//Values /must/ match ordering in optionNames, or everything loads wrong.
|
//Profile settings
|
||||||
//Profile settings
|
ACTIVE_THEME,
|
||||||
ACTIVE_THEME,
|
ACTIVE_MODE,
|
||||||
ACTIVE_MODE,
|
MUSICVOLUME,
|
||||||
MUSICVOLUME,
|
SFXVOLUME,
|
||||||
SFXVOLUME,
|
DIFFICULTY,
|
||||||
DIFFICULTY,
|
CHEATMODE,
|
||||||
CHEATMODE,
|
OPTIMIZE_HAND,
|
||||||
OPTIMIZE_HAND,
|
CHEATMODEAIDECK,
|
||||||
CHEATMODEAIDECK,
|
OSD,
|
||||||
OSD,
|
CLOSEDHAND,
|
||||||
CLOSEDHAND,
|
HANDDIRECTION,
|
||||||
HANDDIRECTION,
|
MANADISPLAY,
|
||||||
MANADISPLAY,
|
REVERSETRIGGERS,
|
||||||
REVERSETRIGGERS,
|
DISABLECARDS,
|
||||||
DISABLECARDS,
|
MAX_GRADE,
|
||||||
MAX_GRADE,
|
ASPHASES,
|
||||||
ASPHASES,
|
FIRSTPLAYER,
|
||||||
ECON_DIFFICULTY,
|
ECON_DIFFICULTY,
|
||||||
TRANSITIONS,
|
TRANSITIONS,
|
||||||
GUI_STYLE,
|
GUI_STYLE,
|
||||||
INTERRUPT_SECONDS,
|
INTERRUPT_SECONDS,
|
||||||
KEY_BINDINGS,
|
KEY_BINDINGS,
|
||||||
AIDECKS_UNLOCKED,
|
AIDECKS_UNLOCKED,
|
||||||
//My interrupts
|
//My interrupts
|
||||||
INTERRUPTMYSPELLS,
|
INTERRUPTMYSPELLS,
|
||||||
INTERRUPTMYABILITIES,
|
INTERRUPTMYABILITIES,
|
||||||
//Other interrupts
|
//Other interrupts
|
||||||
INTERRUPT_BEFOREBEGIN,
|
INTERRUPT_BEFOREBEGIN,
|
||||||
INTERRUPT_UNTAP,
|
INTERRUPT_UNTAP,
|
||||||
INTERRUPT_UPKEEP,
|
INTERRUPT_UPKEEP,
|
||||||
INTERRUPT_DRAW,
|
INTERRUPT_DRAW,
|
||||||
INTERRUPT_FIRSTMAIN,
|
INTERRUPT_FIRSTMAIN,
|
||||||
INTERRUPT_BEGINCOMBAT,
|
INTERRUPT_BEGINCOMBAT,
|
||||||
INTERRUPT_ATTACKERS,
|
INTERRUPT_ATTACKERS,
|
||||||
INTERRUPT_BLOCKERS,
|
INTERRUPT_BLOCKERS,
|
||||||
INTERRUPT_DAMAGE,
|
INTERRUPT_DAMAGE,
|
||||||
INTERRUPT_ENDCOMBAT,
|
INTERRUPT_ENDCOMBAT,
|
||||||
INTERRUPT_SECONDMAIN,
|
INTERRUPT_SECONDMAIN,
|
||||||
INTERRUPT_ENDTURN,
|
INTERRUPT_ENDTURN,
|
||||||
INTERRUPT_CLEANUP,
|
INTERRUPT_CLEANUP,
|
||||||
INTERRUPT_AFTEREND,
|
INTERRUPT_AFTEREND,
|
||||||
BEGIN_AWARDS, //Options after this use the GameOptionAward struct, which includes a timestamp.
|
BEGIN_AWARDS, //Options after this use the GameOptionAward struct, which includes a timestamp.
|
||||||
DIFFICULTY_MODE_UNLOCKED = BEGIN_AWARDS,
|
DIFFICULTY_MODE_UNLOCKED = BEGIN_AWARDS,
|
||||||
MOMIR_MODE_UNLOCKED,
|
MOMIR_MODE_UNLOCKED,
|
||||||
EVILTWIN_MODE_UNLOCKED,
|
EVILTWIN_MODE_UNLOCKED,
|
||||||
RANDOMDECK_MODE_UNLOCKED,
|
RANDOMDECK_MODE_UNLOCKED,
|
||||||
AWARD_COLLECTOR,
|
AWARD_COLLECTOR,
|
||||||
LAST_NAMED, //Any option after this does not look up in optionNames.
|
LAST_NAMED, //Any option after this does not look up in optionNames.
|
||||||
SET_UNLOCKS = LAST_NAMED + 1,
|
SET_UNLOCKS = LAST_NAMED + 1, //For sets.
|
||||||
//For sets.
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int optionSet(int setID);
|
static int optionSet(int setID);
|
||||||
static int optionInterrupt(int gamePhase);
|
static int optionInterrupt(int gamePhase);
|
||||||
|
|
||||||
static int getID(string name);
|
static int getID(string name);
|
||||||
static string getName(int option);
|
static string getName(int option);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const string optionNames[];
|
static const string optionNames[];
|
||||||
};
|
};
|
||||||
|
|
||||||
class GameOption
|
class GameOption {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
virtual ~GameOption()
|
virtual ~GameOption() {};
|
||||||
{
|
int number;
|
||||||
}
|
string str;
|
||||||
;
|
//All calls to asColor should include a fallback color for people without a theme.
|
||||||
int number;
|
PIXEL_TYPE asColor(PIXEL_TYPE fallback = ARGB(255,255,255,255));
|
||||||
string str;
|
|
||||||
//All calls to asColor should include a fallback color for people without a theme.
|
|
||||||
PIXEL_TYPE asColor(PIXEL_TYPE fallback = ARGB(255,255,255,255));
|
|
||||||
|
|
||||||
virtual bool isDefault(); //Returns true when number is 0 and string is "" or "Default"
|
virtual bool isDefault(); //Returns true when number is 0 and string is "" or "Default"
|
||||||
virtual string menuStr(); //The string we'll use for GameStateOptions.
|
virtual string menuStr(); //The string we'll use for GameStateOptions.
|
||||||
virtual bool write(std::ofstream * file, string name);
|
virtual bool write(std::ofstream * file, string name);
|
||||||
virtual bool read(string input);
|
virtual bool read(string input);
|
||||||
|
|
||||||
GameOption(int value = 0);
|
GameOption(int value = 0);
|
||||||
GameOption(string);
|
GameOption(string);
|
||||||
GameOption(int, string);
|
GameOption(int, string);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EnumDefinition
|
struct EnumDefinition {
|
||||||
{
|
int findIndex(int value);
|
||||||
int findIndex(int value);
|
|
||||||
|
|
||||||
typedef pair<int, string> assoc;
|
typedef pair<int, string> assoc;
|
||||||
vector<assoc> values;
|
vector<assoc> values;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GameOptionEnum: public GameOption
|
class GameOptionEnum: public GameOption {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
virtual string menuStr();
|
virtual string menuStr();
|
||||||
virtual bool write(std::ofstream * file, string name);
|
virtual bool write(std::ofstream * file, string name);
|
||||||
virtual bool read(string input);
|
virtual bool read(string input);
|
||||||
EnumDefinition * def;
|
EnumDefinition * def;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GameOptionAward: public GameOption
|
class GameOptionAward: public GameOption {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
GameOptionAward();
|
GameOptionAward();
|
||||||
virtual string menuStr();
|
virtual string menuStr();
|
||||||
virtual bool write(std::ofstream * file, string name);
|
virtual bool write(std::ofstream * file, string name);
|
||||||
virtual bool read(string input);
|
virtual bool read(string input);
|
||||||
virtual bool giveAward(); //Returns false if already awarded
|
virtual bool giveAward(); //Returns false if already awarded
|
||||||
virtual bool isViewed();
|
virtual bool isViewed();
|
||||||
virtual void setViewed(bool v = true)
|
virtual void setViewed(bool v = true) {viewed = v;};
|
||||||
{
|
|
||||||
viewed = v;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
private:
|
private:
|
||||||
time_t achieved; //When was it awarded?
|
time_t achieved; //When was it awarded?
|
||||||
bool viewed; //Flag it as "New!" or not.
|
bool viewed; //Flag it as "New!" or not.
|
||||||
};
|
};
|
||||||
|
|
||||||
class GameOptionKeyBindings: public GameOption
|
class GameOptionKeyBindings : public GameOption {
|
||||||
{
|
virtual bool read(string input);
|
||||||
virtual bool read(string input);
|
virtual bool write(std::ofstream*, string);
|
||||||
virtual bool write(std::ofstream*, string);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class OptionVolume: public EnumDefinition
|
class OptionVolume: public EnumDefinition{
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
enum
|
enum { MUTE = 0, MAX = 100 };
|
||||||
{
|
static EnumDefinition * getInstance() {return &mDef;};
|
||||||
MUTE = 0, MAX = 100
|
|
||||||
};
|
|
||||||
static EnumDefinition * getInstance()
|
|
||||||
{
|
|
||||||
return &mDef;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
private:
|
private:
|
||||||
OptionVolume();
|
OptionVolume();
|
||||||
static OptionVolume mDef;
|
static OptionVolume mDef;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OptionClosedHand: public EnumDefinition
|
|
||||||
{
|
class OptionClosedHand: public EnumDefinition {
|
||||||
public:
|
public:
|
||||||
enum
|
enum { INVISIBLE = 0, VISIBLE = 1 };
|
||||||
{
|
static EnumDefinition * getInstance() {return &mDef;};
|
||||||
INVISIBLE = 0, VISIBLE = 1
|
|
||||||
};
|
|
||||||
static EnumDefinition * getInstance()
|
|
||||||
{
|
|
||||||
return &mDef;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
private:
|
private:
|
||||||
OptionClosedHand();
|
OptionClosedHand();
|
||||||
static OptionClosedHand mDef;
|
static OptionClosedHand mDef;
|
||||||
};
|
};
|
||||||
class OptionHandDirection: public EnumDefinition
|
class OptionHandDirection: public EnumDefinition {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
enum
|
enum { VERTICAL = 0, HORIZONTAL = 1};
|
||||||
{
|
static EnumDefinition * getInstance() {return &mDef;};
|
||||||
VERTICAL = 0, HORIZONTAL = 1
|
|
||||||
};
|
|
||||||
static EnumDefinition * getInstance()
|
|
||||||
{
|
|
||||||
return &mDef;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
private:
|
private:
|
||||||
OptionHandDirection();
|
OptionHandDirection();
|
||||||
static OptionHandDirection mDef;
|
static OptionHandDirection mDef;
|
||||||
};
|
};
|
||||||
class OptionManaDisplay: public EnumDefinition
|
class OptionManaDisplay: public EnumDefinition {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
enum
|
enum { DYNAMIC = 0, STATIC = 1, NOSTARSDYNAMIC = 2, BOTH = 3};
|
||||||
{
|
static EnumDefinition * getInstance() {return &mDef;};
|
||||||
DYNAMIC = 0, STATIC = 1, NOSTARSDYNAMIC = 2, BOTH = 3
|
|
||||||
};
|
|
||||||
static EnumDefinition * getInstance()
|
|
||||||
{
|
|
||||||
return &mDef;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
private:
|
private:
|
||||||
OptionManaDisplay();
|
OptionManaDisplay();
|
||||||
static OptionManaDisplay mDef;
|
static OptionManaDisplay mDef;
|
||||||
};
|
};
|
||||||
class OptionMaxGrade: public EnumDefinition
|
class OptionMaxGrade: public EnumDefinition {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
static EnumDefinition * getInstance()
|
static EnumDefinition * getInstance() {return &mDef;};
|
||||||
{
|
|
||||||
return &mDef;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
private:
|
private:
|
||||||
OptionMaxGrade();
|
OptionMaxGrade();
|
||||||
static OptionMaxGrade mDef;
|
static OptionMaxGrade mDef;
|
||||||
};
|
};
|
||||||
class OptionASkipPhase: public EnumDefinition
|
class OptionASkipPhase: public EnumDefinition {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
static EnumDefinition * getInstance()
|
static EnumDefinition * getInstance() {return &mDef;};
|
||||||
{
|
|
||||||
return &mDef;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
private:
|
private:
|
||||||
OptionASkipPhase();
|
OptionASkipPhase();
|
||||||
static OptionASkipPhase mDef;
|
static OptionASkipPhase mDef;
|
||||||
};
|
};
|
||||||
class OptionEconDifficulty: public EnumDefinition
|
class OptionWhosFirst: public EnumDefinition {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
static EnumDefinition * getInstance()
|
enum { WHO_P = 0, WHO_O = 1, WHO_R = 2};
|
||||||
{
|
static EnumDefinition * getInstance() {return &mDef;};
|
||||||
return &mDef;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
private:
|
private:
|
||||||
OptionEconDifficulty();
|
OptionWhosFirst();
|
||||||
static OptionEconDifficulty mDef;
|
static OptionWhosFirst mDef;
|
||||||
};
|
};
|
||||||
class OptionDifficulty: public EnumDefinition
|
class OptionEconDifficulty: public EnumDefinition {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
enum
|
static EnumDefinition * getInstance() {return &mDef;};
|
||||||
{
|
|
||||||
NORMAL = 0, HARD = 1, HARDER = 2, EVIL = 3
|
|
||||||
};
|
|
||||||
static EnumDefinition * getInstance()
|
|
||||||
{
|
|
||||||
return &mDef;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
private:
|
private:
|
||||||
OptionDifficulty();
|
OptionEconDifficulty();
|
||||||
static OptionDifficulty mDef;
|
static OptionEconDifficulty mDef;
|
||||||
|
};
|
||||||
|
class OptionDifficulty: public EnumDefinition {
|
||||||
|
public:
|
||||||
|
enum { NORMAL = 0, HARD = 1, HARDER = 2, EVIL = 3};
|
||||||
|
static EnumDefinition * getInstance() {return &mDef;};
|
||||||
|
private:
|
||||||
|
OptionDifficulty();
|
||||||
|
static OptionDifficulty mDef;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GameOptions
|
class GameOptions {
|
||||||
{
|
public:
|
||||||
public:
|
string mFilename;
|
||||||
string mFilename;
|
int save();
|
||||||
int save();
|
int load();
|
||||||
int load();
|
|
||||||
|
|
||||||
GameOption * get(int);
|
GameOption * get(int);
|
||||||
GameOption& operator[](int);
|
GameOption& operator[](int);
|
||||||
GameOptions(string filename);
|
GameOptions(string filename);
|
||||||
~GameOptions();
|
~GameOptions();
|
||||||
|
|
||||||
|
private:
|
||||||
|
vector<GameOption*> values;
|
||||||
|
vector<string> unknown;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GameSettings{
|
||||||
|
public:
|
||||||
|
friend class GameApp;
|
||||||
|
GameSettings();
|
||||||
|
~GameSettings();
|
||||||
|
int save();
|
||||||
|
|
||||||
|
SimplePad * keypadStart(string input, string * _dest = NULL, bool _cancel=true, bool _numpad=false, int _x = SCREEN_WIDTH/2, int _y = SCREEN_HEIGHT/2);
|
||||||
|
string keypadFinish();
|
||||||
|
void keypadShutdown();
|
||||||
|
void keypadTitle(string set);
|
||||||
|
bool keypadActive() {if(keypad) return keypad->isActive(); return false;};
|
||||||
|
void keypadUpdate(float dt) {if(keypad) keypad->Update(dt);};
|
||||||
|
void keypadRender() {if(keypad) keypad->Render();};
|
||||||
|
|
||||||
|
bool newAward();
|
||||||
|
|
||||||
|
//These return a filepath accurate to the current mode/profile/theme, and can
|
||||||
|
//optionally fallback to a file within a certain directory.
|
||||||
|
//The sanity=false option returns the adjusted path even if the file doesn't exist.
|
||||||
|
string profileFile(string filename="", string fallback="", bool sanity=false,bool relative=false);
|
||||||
|
|
||||||
|
void reloadProfile(); //Reloads profile using current options[ACTIVE_PROFILE]
|
||||||
|
void checkProfile(); //Confirms that a profile is loaded and contains a collection.
|
||||||
|
void createUsersFirstDeck(int setId);
|
||||||
|
|
||||||
|
GameOption * get(int);
|
||||||
|
GameOption& operator[](int);
|
||||||
|
|
||||||
|
GameOptions* profileOptions;
|
||||||
|
GameOptions* globalOptions;
|
||||||
|
|
||||||
|
static GameOption invalid_option;
|
||||||
|
|
||||||
|
WStyle * getStyle();
|
||||||
|
StyleManager * getStyleMan();
|
||||||
|
void automaticStyle(Player * p1, Player * p2);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
vector<GameOption*> values;
|
GameApp * theGame;
|
||||||
vector<string> unknown;
|
SimplePad * keypad;
|
||||||
};
|
StyleManager * styleMan;
|
||||||
|
|
||||||
class GameSettings
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
friend class GameApp;
|
|
||||||
GameSettings();
|
|
||||||
~GameSettings();
|
|
||||||
int save();
|
|
||||||
|
|
||||||
SimplePad * keypadStart(string input, string * _dest = NULL, bool _cancel = true, bool _numpad = false, int _x = SCREEN_WIDTH
|
|
||||||
/ 2, int _y = SCREEN_HEIGHT / 2);
|
|
||||||
string keypadFinish();
|
|
||||||
void keypadShutdown();
|
|
||||||
void keypadTitle(string set);
|
|
||||||
bool keypadActive()
|
|
||||||
{
|
|
||||||
if (keypad)
|
|
||||||
return keypad->isActive();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
void keypadUpdate(float dt)
|
|
||||||
{
|
|
||||||
if (keypad)
|
|
||||||
keypad->Update(dt);
|
|
||||||
}
|
|
||||||
;
|
|
||||||
void keypadRender()
|
|
||||||
{
|
|
||||||
if (keypad)
|
|
||||||
keypad->Render();
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
bool newAward();
|
|
||||||
|
|
||||||
//These return a filepath accurate to the current mode/profile/theme, and can
|
|
||||||
//optionally fallback to a file within a certain directory.
|
|
||||||
//The sanity=false option returns the adjusted path even if the file doesn't exist.
|
|
||||||
string profileFile(string filename = "", string fallback = "", bool sanity = false, bool relative = false);
|
|
||||||
|
|
||||||
void reloadProfile(); //Reloads profile using current options[ACTIVE_PROFILE]
|
|
||||||
void checkProfile(); //Confirms that a profile is loaded and contains a collection.
|
|
||||||
void createUsersFirstDeck(int setId);
|
|
||||||
|
|
||||||
GameOption * get(int);
|
|
||||||
GameOption& operator[](int);
|
|
||||||
|
|
||||||
GameOptions* profileOptions;
|
|
||||||
GameOptions* globalOptions;
|
|
||||||
|
|
||||||
static GameOption invalid_option;
|
|
||||||
|
|
||||||
WStyle * getStyle();
|
|
||||||
StyleManager * getStyleMan();
|
|
||||||
void automaticStyle(Player * p1, Player * p2);
|
|
||||||
|
|
||||||
private:
|
|
||||||
GameApp * theGame;
|
|
||||||
SimplePad * keypad;
|
|
||||||
StyleManager * styleMan;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern GameSettings options;
|
extern GameSettings options;
|
||||||
|
|||||||
+342
-327
@@ -1,6 +1,8 @@
|
|||||||
#ifndef _MTGABILITY_H_
|
#ifndef _MTGABILITY_H_
|
||||||
#define _MTGABILITY_H_
|
#define _MTGABILITY_H_
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MTGCardInstance;
|
class MTGCardInstance;
|
||||||
class Spell;
|
class Spell;
|
||||||
class Damageable;
|
class Damageable;
|
||||||
@@ -22,6 +24,7 @@ class Counter;
|
|||||||
using std::string;
|
using std::string;
|
||||||
using std::map;
|
using std::map;
|
||||||
|
|
||||||
|
|
||||||
//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
|
||||||
@@ -37,374 +40,386 @@ using std::map;
|
|||||||
#define PARSER_FOREACH 2
|
#define PARSER_FOREACH 2
|
||||||
#define PARSER_ASLONGAS 3
|
#define PARSER_ASLONGAS 3
|
||||||
|
|
||||||
class MTGAbility: public ActionElement
|
class MTGAbility: public ActionElement{
|
||||||
{
|
protected:
|
||||||
protected:
|
char menuText[50];
|
||||||
char menuText[50];
|
|
||||||
|
|
||||||
GameObserver* game;
|
GameObserver * game;
|
||||||
public:
|
public:
|
||||||
int oneShot;
|
enum {
|
||||||
int forceDestroy;
|
NO_RESTRICTION = 0,
|
||||||
ManaCost* cost;
|
PLAYER_TURN_ONLY = 1,
|
||||||
ManaCost* alternative;
|
AS_SORCERY = 2,
|
||||||
ManaCost* BuyBack;
|
MY_BEFORE_BEGIN = 3,
|
||||||
ManaCost* FlashBack;
|
MY_UNTAP = 4,
|
||||||
ManaCost* Retrace;
|
MY_UPKEEP = 5,
|
||||||
|
MY_DRAW = 6,
|
||||||
|
MY_FIRSTMAIN = 7,
|
||||||
|
MY_COMBATBEGIN = 8,
|
||||||
|
MY_COMBATATTACKERS = 9,
|
||||||
|
MY_COMBATBLOCKERS = 10,
|
||||||
|
MY_COMBATDAMAGE = 11,
|
||||||
|
MY_COMBATEND = 12,
|
||||||
|
MY_SECONDMAIN = 13,
|
||||||
|
MY_ENDOFTURN = 14,
|
||||||
|
MY_EOT = 15,
|
||||||
|
MY_CLEANUP = 16,
|
||||||
|
MY_AFTER_EOT = 17,
|
||||||
|
|
||||||
Targetable* target;
|
OPPONENT_BEFORE_BEGIN = 23,
|
||||||
int aType;
|
OPPONENT_UNTAP = 24,
|
||||||
int naType;
|
OPPONENT_UPKEEP = 25,
|
||||||
int abilitygranted;
|
OPPONENT_DRAW = 26,
|
||||||
int nbcardAmount;
|
OPPONENT_FIRSTMAIN = 27,
|
||||||
MTGCardInstance* source;
|
OPPONENT_COMBATBEGIN = 28,
|
||||||
MTGAbility(int id, MTGCardInstance* card);
|
OPPONENT_COMBATATTACKERS = 29,
|
||||||
MTGAbility(int id, MTGCardInstance* _source, Targetable* _target);
|
OPPONENT_COMBATBLOCKERS = 30,
|
||||||
virtual int testDestroy();
|
OPPONENT_COMBATDAMAGE = 31,
|
||||||
virtual ~MTGAbility();
|
OPPONENT_COMBATEND = 32,
|
||||||
virtual void Render() {}
|
OPPONENT_SECONDMAIN = 33,
|
||||||
virtual int isReactingToClick(MTGCardInstance* card, ManaCost* mana = NULL)
|
OPPONENT_ENDOFTURN = 34,
|
||||||
{
|
OPPONENT_EOT = 35,
|
||||||
return 0;
|
OPPONENT_CLEANUP = 36,
|
||||||
}
|
OPPONENT_AFTER_EOT = 37,
|
||||||
;
|
|
||||||
virtual int reactToClick(MTGCardInstance* card)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
virtual int receiveEvent(WEvent* event)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
virtual void Update(float dt) {};
|
|
||||||
virtual int fireAbility();
|
|
||||||
virtual int stillInUse(MTGCardInstance* card);
|
|
||||||
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 */
|
BEFORE_BEGIN = 43,
|
||||||
/* Todo replace that crap with dynamic casting */
|
UNTAP = 44,
|
||||||
enum
|
UPKEEP = 45,
|
||||||
{
|
DRAW = 46,
|
||||||
UNKNOWN = 0,
|
FIRSTMAIN = 47,
|
||||||
MANA_PRODUCER = 1,
|
COMBATBEGIN = 48,
|
||||||
MTG_ATTACK_RULE = 2,
|
COMBATATTACKERS = 49,
|
||||||
DAMAGER = 3,
|
COMBATBLOCKERS = 50,
|
||||||
STANDARD_REGENERATE = 4,
|
COMBATDAMAGE = 51,
|
||||||
PUT_INTO_PLAY = 5,
|
COMBATEND = 52,
|
||||||
MOMIR = 6,
|
SECONDMAIN = 53,
|
||||||
MTG_BLOCK_RULE = 7,
|
ENDOFTURN = 54,
|
||||||
ALTERNATIVE_COST = 8,
|
EOT = 55,
|
||||||
BUYBACK_COST = 9,
|
CLEANUP = 56,
|
||||||
FLASHBACK_COST = 10,
|
AFTER_EOT = 57,
|
||||||
RETRACE_COST = 11,
|
|
||||||
MTG_COMBATTRIGGERS_RULE = 12,
|
VAMPIRES = 60,
|
||||||
STANDARD_PREVENT = 13,
|
LESS_CREATURES = 61,
|
||||||
STANDARD_EQUIP = 14,
|
SNOW_LAND_INPLAY =62,
|
||||||
STANDARD_LEVELUP = 15,
|
CASTED_A_SPELL = 63,
|
||||||
FOREACH = 16,
|
ONE_OF_AKIND = 64,
|
||||||
STANDARD_DRAW = 17,
|
FOURTHTURN = 65,
|
||||||
STANDARD_PUMP = 18,
|
BEFORECOMBATDAMAGE = 66,
|
||||||
STANDARD_BECOMES = 19,
|
AFTERCOMBAT = 67,
|
||||||
UPCOST = 20,
|
DURINGCOMBAT = 68,
|
||||||
STANDARDABILITYGRANT = 21,
|
OPPONENT_TURN_ONLY = 69,
|
||||||
UNTAPPER = 22,
|
};
|
||||||
TAPPER = 23,
|
int allowedToCast(MTGCardInstance * card,Player * player);
|
||||||
LIFER = 24,
|
int allowedToAltCast(MTGCardInstance * card,Player * player);
|
||||||
CLONING = 25,
|
int oneShot;
|
||||||
};
|
int forceDestroy;
|
||||||
|
ManaCost * cost;
|
||||||
|
ManaCost * alternative;
|
||||||
|
ManaCost * BuyBack;
|
||||||
|
ManaCost * FlashBack;
|
||||||
|
ManaCost * Retrace;
|
||||||
|
ManaCost * morph;
|
||||||
|
|
||||||
|
Targetable * target;
|
||||||
|
int aType;
|
||||||
|
int naType;
|
||||||
|
int abilitygranted;
|
||||||
|
int nbcardAmount;
|
||||||
|
MTGCardInstance * source;
|
||||||
|
MTGAbility(int id, MTGCardInstance * card);
|
||||||
|
MTGAbility(int id, MTGCardInstance * _source, Targetable * _target);
|
||||||
|
virtual int testDestroy();
|
||||||
|
virtual ~MTGAbility();
|
||||||
|
virtual void Render(){};
|
||||||
|
virtual int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL){return 0;};
|
||||||
|
virtual int reactToClick(MTGCardInstance * card){return 0;};
|
||||||
|
virtual int receiveEvent(WEvent * event){return 0;};
|
||||||
|
virtual void Update(float dt){};
|
||||||
|
virtual int fireAbility();
|
||||||
|
virtual int stillInUse(MTGCardInstance * card);
|
||||||
|
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 */
|
||||||
|
enum {
|
||||||
|
UNKNOWN = 0,
|
||||||
|
MANA_PRODUCER = 1,
|
||||||
|
MTG_ATTACK_RULE = 2,
|
||||||
|
DAMAGER = 3,
|
||||||
|
STANDARD_REGENERATE = 4,
|
||||||
|
PUT_INTO_PLAY = 5,
|
||||||
|
MOMIR = 6,
|
||||||
|
MTG_BLOCK_RULE = 7,
|
||||||
|
ALTERNATIVE_COST = 8,
|
||||||
|
BUYBACK_COST = 9,
|
||||||
|
FLASHBACK_COST = 10,
|
||||||
|
RETRACE_COST = 11,
|
||||||
|
MTG_COMBATTRIGGERS_RULE = 12,
|
||||||
|
STANDARD_PREVENT = 13,
|
||||||
|
STANDARD_EQUIP = 14,
|
||||||
|
STANDARD_LEVELUP = 15,
|
||||||
|
FOREACH = 16,
|
||||||
|
STANDARD_DRAW = 17,
|
||||||
|
STANDARD_PUMP = 18,
|
||||||
|
STANDARD_BECOMES = 19,
|
||||||
|
UPCOST = 20,
|
||||||
|
STANDARDABILITYGRANT = 21,
|
||||||
|
UNTAPPER = 22,
|
||||||
|
TAPPER = 23,
|
||||||
|
LIFER = 24,
|
||||||
|
CLONING = 25,
|
||||||
|
STANDARD_TEACH = 26,
|
||||||
|
STANDARD_TOKENCREATOR = 27,
|
||||||
|
MORPH_COST = 28,
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class NestedAbility
|
class NestedAbility{
|
||||||
{
|
public:
|
||||||
public:
|
MTGAbility * ability;
|
||||||
MTGAbility* ability;
|
NestedAbility(MTGAbility * _ability);
|
||||||
NestedAbility(MTGAbility* _ability);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
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, Targetable * _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(){return 0;};
|
||||||
;
|
virtual int triggerOnEvent(WEvent * e){return 0;};
|
||||||
virtual int trigger()
|
int receiveEvent(WEvent * e);
|
||||||
{
|
virtual int resolve() = 0;
|
||||||
return 0;
|
virtual TriggeredAbility* clone() const = 0;
|
||||||
}
|
virtual ostream& toString(ostream& out) const;
|
||||||
;
|
|
||||||
virtual int triggerOnEvent(WEvent* e)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
int receiveEvent(WEvent* e);
|
|
||||||
virtual int resolve() = 0;
|
|
||||||
virtual TriggeredAbility* clone() const = 0;
|
|
||||||
virtual ostream& toString(ostream& out) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ActivatedAbility: public MTGAbility
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
NO_RESTRICTION = 0,
|
|
||||||
PLAYER_TURN_ONLY = 1,
|
|
||||||
AS_SORCERY = 2,
|
|
||||||
MY_BEFORE_BEGIN = 3,
|
|
||||||
MY_UNTAP = 4,
|
|
||||||
MY_UPKEEP = 5,
|
|
||||||
MY_DRAW = 6,
|
|
||||||
MY_FIRSTMAIN = 7,
|
|
||||||
MY_COMBATBEGIN = 8,
|
|
||||||
MY_COMBATATTACKERS = 9,
|
|
||||||
MY_COMBATBLOCKERS = 10,
|
|
||||||
MY_COMBATDAMAGE = 11,
|
|
||||||
MY_COMBATEND = 12,
|
|
||||||
MY_SECONDMAIN = 13,
|
|
||||||
MY_ENDOFTURN = 14,
|
|
||||||
MY_EOT = 15,
|
|
||||||
MY_CLEANUP = 16,
|
|
||||||
MY_AFTER_EOT = 17,
|
|
||||||
|
|
||||||
OPPONENT_BEFORE_BEGIN = 23,
|
class ActivatedAbility:public MTGAbility{
|
||||||
OPPONENT_UNTAP = 24,
|
public:
|
||||||
OPPONENT_UPKEEP = 25,
|
enum {
|
||||||
OPPONENT_DRAW = 26,
|
NO_RESTRICTION = 0,
|
||||||
OPPONENT_FIRSTMAIN = 27,
|
PLAYER_TURN_ONLY = 1,
|
||||||
OPPONENT_COMBATBEGIN = 28,
|
AS_SORCERY = 2,
|
||||||
OPPONENT_COMBATATTACKERS = 29,
|
MY_BEFORE_BEGIN = 3,
|
||||||
OPPONENT_COMBATBLOCKERS = 30,
|
MY_UNTAP = 4,
|
||||||
OPPONENT_COMBATDAMAGE = 31,
|
MY_UPKEEP = 5,
|
||||||
OPPONENT_COMBATEND = 32,
|
MY_DRAW = 6,
|
||||||
OPPONENT_SECONDMAIN = 33,
|
MY_FIRSTMAIN = 7,
|
||||||
OPPONENT_ENDOFTURN = 34,
|
MY_COMBATBEGIN = 8,
|
||||||
OPPONENT_EOT = 35,
|
MY_COMBATATTACKERS = 9,
|
||||||
OPPONENT_CLEANUP = 36,
|
MY_COMBATBLOCKERS = 10,
|
||||||
OPPONENT_AFTER_EOT = 37,
|
MY_COMBATDAMAGE = 11,
|
||||||
|
MY_COMBATEND = 12,
|
||||||
|
MY_SECONDMAIN = 13,
|
||||||
|
MY_ENDOFTURN = 14,
|
||||||
|
MY_EOT = 15,
|
||||||
|
MY_CLEANUP = 16,
|
||||||
|
MY_AFTER_EOT = 17,
|
||||||
|
|
||||||
BEFORE_BEGIN = 43,
|
OPPONENT_BEFORE_BEGIN = 23,
|
||||||
UNTAP = 44,
|
OPPONENT_UNTAP = 24,
|
||||||
UPKEEP = 45,
|
OPPONENT_UPKEEP = 25,
|
||||||
DRAW = 46,
|
OPPONENT_DRAW = 26,
|
||||||
FIRSTMAIN = 47,
|
OPPONENT_FIRSTMAIN = 27,
|
||||||
COMBATBEGIN = 48,
|
OPPONENT_COMBATBEGIN = 28,
|
||||||
COMBATATTACKERS = 49,
|
OPPONENT_COMBATATTACKERS = 29,
|
||||||
COMBATBLOCKERS = 50,
|
OPPONENT_COMBATBLOCKERS = 30,
|
||||||
COMBATDAMAGE = 51,
|
OPPONENT_COMBATDAMAGE = 31,
|
||||||
COMBATEND = 52,
|
OPPONENT_COMBATEND = 32,
|
||||||
SECONDMAIN = 53,
|
OPPONENT_SECONDMAIN = 33,
|
||||||
ENDOFTURN = 54,
|
OPPONENT_ENDOFTURN = 34,
|
||||||
EOT = 55,
|
OPPONENT_EOT = 35,
|
||||||
CLEANUP = 56,
|
OPPONENT_CLEANUP = 36,
|
||||||
AFTER_EOT = 57,
|
OPPONENT_AFTER_EOT = 37,
|
||||||
};
|
|
||||||
ManaCost* abilityCost;
|
BEFORE_BEGIN = 43,
|
||||||
int restrictions;
|
UNTAP = 44,
|
||||||
int needsTapping;
|
UPKEEP = 45,
|
||||||
ActivatedAbility(int id, MTGCardInstance* card, ManaCost* _cost = NULL, int _restrictions = NO_RESTRICTION, int tap = 1);
|
DRAW = 46,
|
||||||
virtual ~ActivatedAbility();
|
FIRSTMAIN = 47,
|
||||||
virtual int reactToClick(MTGCardInstance* card);
|
COMBATBEGIN = 48,
|
||||||
virtual int isReactingToClick(MTGCardInstance* card, ManaCost* mana = NULL);
|
COMBATATTACKERS = 49,
|
||||||
virtual int reactToTargetClick(Targetable* object);
|
COMBATBLOCKERS = 50,
|
||||||
virtual int resolve() = 0;
|
COMBATDAMAGE = 51,
|
||||||
virtual ActivatedAbility* clone() const = 0;
|
COMBATEND = 52,
|
||||||
virtual ostream& toString(ostream& out) const;
|
SECONDMAIN = 53,
|
||||||
|
ENDOFTURN = 54,
|
||||||
|
EOT = 55,
|
||||||
|
CLEANUP = 56,
|
||||||
|
AFTER_EOT = 57,
|
||||||
|
|
||||||
|
OPPONENT_TURN_ONLY = 69,
|
||||||
|
};
|
||||||
|
ManaCost * abilityCost;
|
||||||
|
int restrictions;
|
||||||
|
int needsTapping;
|
||||||
|
ActivatedAbility(int id, MTGCardInstance * card,ManaCost * _cost = NULL, int _restrictions = NO_RESTRICTION,int tap = 1);
|
||||||
|
virtual ~ActivatedAbility();
|
||||||
|
virtual int reactToClick(MTGCardInstance * card);
|
||||||
|
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 NestedAbility
|
class TargetAbility:public ActivatedAbility, public NestedAbility{
|
||||||
{
|
public:
|
||||||
public:
|
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 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 TargetAbility* clone() const = 0;
|
virtual void Render();
|
||||||
virtual void Render();
|
virtual int resolve();
|
||||||
virtual int resolve();
|
virtual const char * getMenuText();
|
||||||
virtual const char* getMenuText();
|
virtual ostream& toString(ostream& out) const;
|
||||||
virtual ostream& toString(ostream& out) const;
|
~TargetAbility();
|
||||||
~TargetAbility();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class InstantAbility: public MTGAbility
|
class InstantAbility:public MTGAbility{
|
||||||
{
|
public:
|
||||||
public:
|
int init;
|
||||||
int init;
|
virtual void Update(float dt);
|
||||||
virtual void Update(float dt);
|
virtual int testDestroy();
|
||||||
virtual int testDestroy();
|
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()
|
virtual InstantAbility* clone() const = 0;
|
||||||
{
|
virtual ostream& toString(ostream& out) const;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
virtual InstantAbility* clone() const = 0;
|
|
||||||
virtual ostream& toString(ostream& out) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* State based effects. This class works ONLY for InPlay and needs to be extended for other areas of the game !!! */
|
/* State based effects. This class works ONLY for InPlay and needs to be extended for other areas of the game !!! */
|
||||||
class ListMaintainerAbility: public MTGAbility
|
class ListMaintainerAbility:public MTGAbility{
|
||||||
{
|
public:
|
||||||
public:
|
map<MTGCardInstance *,bool> cards;
|
||||||
map<MTGCardInstance *, bool> cards;
|
map<Player *,bool> players;
|
||||||
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,Damageable * _target):MTGAbility(_id, _source, _target){};
|
||||||
}
|
virtual void Update(float dt);
|
||||||
;
|
void updateTargets();
|
||||||
ListMaintainerAbility(int _id, MTGCardInstance *_source) : MTGAbility(_id, _source)
|
virtual bool canTarget(MTGGameZone * zone);
|
||||||
{
|
virtual int canBeInList(MTGCardInstance * card) = 0;
|
||||||
}
|
virtual int added(MTGCardInstance * card) = 0;
|
||||||
;
|
virtual int removed(MTGCardInstance * card) = 0;
|
||||||
ListMaintainerAbility(int _id, MTGCardInstance *_source, Damageable* _target) : MTGAbility(_id, _source, _target)
|
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 void Update(float dt);
|
virtual ListMaintainerAbility* clone() const = 0;
|
||||||
void updateTargets();
|
virtual ostream& toString(ostream& out) const;
|
||||||
virtual bool canTarget(MTGGameZone* zone);
|
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class TriggerAtPhase: public TriggeredAbility
|
class TriggerAtPhase:public TriggeredAbility{
|
||||||
{
|
public:
|
||||||
public:
|
int phaseId;
|
||||||
int phaseId;
|
int who;
|
||||||
int who;
|
bool sourceUntapped;
|
||||||
TriggerAtPhase(int id, MTGCardInstance* source, Targetable* target, int _phaseId, int who = 0);
|
bool sourceTap;
|
||||||
virtual int trigger();
|
bool lifelost;
|
||||||
int resolve()
|
int lifeamount;
|
||||||
{
|
TriggerAtPhase(int id, MTGCardInstance * source, Targetable * target,int _phaseId, int who = 0,bool sourceUntapped = false,bool sourceTap = false,bool lifelost = false, int lifeamount = 0);
|
||||||
return 0;
|
virtual int trigger();
|
||||||
}
|
int resolve(){return 0;};
|
||||||
;
|
virtual TriggerAtPhase* clone() const;
|
||||||
virtual TriggerAtPhase* clone() const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class TriggerNextPhase: public TriggerAtPhase
|
class TriggerNextPhase:public TriggerAtPhase{
|
||||||
{
|
public:
|
||||||
public:
|
int destroyActivated;
|
||||||
int destroyActivated;
|
bool sourceUntapped;
|
||||||
TriggerNextPhase(int id, MTGCardInstance* source, Targetable* target, int _phaseId, int who = 0);
|
bool sourceTap;
|
||||||
virtual TriggerNextPhase* clone() const;
|
TriggerNextPhase(int id, MTGCardInstance * source, Targetable * target,int _phaseId, int who = 0,bool sourceUntapped = false,bool sourceTap = false);
|
||||||
virtual int testDestroy();
|
virtual TriggerNextPhase* clone() const;
|
||||||
|
virtual int testDestroy();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class GenericTriggeredAbility: public TriggeredAbility, public NestedAbility
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
TriggeredAbility* t;
|
|
||||||
queue<Targetable *> targets;
|
|
||||||
MTGAbility* destroyCondition;
|
|
||||||
GenericTriggeredAbility(int id, MTGCardInstance* _source, TriggeredAbility* _t, MTGAbility* a, MTGAbility* dc = NULL,
|
|
||||||
Targetable* _target = NULL);
|
|
||||||
virtual int trigger();
|
|
||||||
virtual int triggerOnEvent(WEvent* e);
|
|
||||||
virtual int resolve();
|
|
||||||
virtual int testDestroy();
|
|
||||||
|
|
||||||
Targetable* getTriggerTarget(WEvent* e, MTGAbility* a);
|
class GenericTriggeredAbility:public TriggeredAbility, public NestedAbility{
|
||||||
void setTriggerTargets(Targetable* ta, MTGAbility* a);
|
public:
|
||||||
|
TriggeredAbility * t;
|
||||||
|
queue<Targetable *> targets;
|
||||||
|
MTGAbility * destroyCondition;
|
||||||
|
GenericTriggeredAbility(int id, MTGCardInstance * _source, TriggeredAbility * _t, MTGAbility * a,MTGAbility * dc = NULL, Targetable * _target = NULL);
|
||||||
|
virtual int trigger();
|
||||||
|
virtual int triggerOnEvent(WEvent * e);
|
||||||
|
virtual int resolve();
|
||||||
|
virtual int testDestroy();
|
||||||
|
|
||||||
void Update(float dt);
|
Targetable * getTriggerTarget(WEvent * e, MTGAbility * a);
|
||||||
virtual GenericTriggeredAbility* clone() const;
|
void setTriggerTargets(Targetable * ta, MTGAbility * a);
|
||||||
const char* getMenuText();
|
|
||||||
~GenericTriggeredAbility();
|
void Update(float dt);
|
||||||
|
virtual GenericTriggeredAbility* clone() const;
|
||||||
|
const char * getMenuText();
|
||||||
|
~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);
|
TriggeredAbility * parseTrigger(string s, string magicText, int id, Spell * spell, MTGCardInstance *card, Targetable * target);
|
||||||
TriggeredAbility* parseTrigger(string s, string magicText, int id, Spell* spell, MTGCardInstance *card, Targetable* target);
|
int parseRestriction(string s);
|
||||||
int parseRestriction(string s);
|
MTGAbility * getAlternateCost( string s, int id, Spell *spell, MTGCardInstance *card );
|
||||||
MTGAbility* getAlternateCost(string s, int id, Spell *spell, MTGCardInstance *card);
|
MTGAbility * getManaReduxAbility(string s, int id, Spell *spell, MTGCardInstance *card, MTGCardInstance *target);
|
||||||
MTGAbility* getManaReduxAbility(string s, int id, Spell *spell, MTGCardInstance *card, MTGCardInstance *target);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Counter* parseCounter(string s, MTGCardInstance* target, Spell* spell = NULL);
|
Counter * parseCounter(string s, MTGCardInstance * target, Spell * spell = NULL);
|
||||||
int parsePowerToughness(string s, int* power, int* toughness);
|
int parsePowerToughness(string s, int *power, int *toughness);
|
||||||
int getAbilities(vector<MTGAbility *>* v, Spell* spell, MTGCardInstance* card = NULL, int id = 0, MTGGameZone* dest = NULL);
|
int getAbilities(vector<MTGAbility *> * v, Spell * spell, MTGCardInstance * card = NULL, int id = 0,MTGGameZone * dest = NULL);
|
||||||
MTGAbility* parseMagicLine(string s, int id, Spell* spell, MTGCardInstance *card, int activated = 0, int forceUEOT = 0,
|
MTGAbility * parseMagicLine(string s, int id, Spell * spell, MTGCardInstance *card, int activated = 0, int forceUEOT = 0,int oneShot = 0,int forceForever = 0, MTGGameZone * dest = NULL);
|
||||||
int oneShot = 0, int forceForever = 0, MTGGameZone* dest = NULL);
|
|
||||||
|
|
||||||
int abilityEfficiency(MTGAbility* a, Player* p, int mode = MODE_ABILITY, TargetChooser* tc = NULL);
|
int abilityEfficiency(MTGAbility * a, Player * p, int mode = MODE_ABILITY, TargetChooser * tc = NULL);
|
||||||
int magicText(int id, Spell* spell, MTGCardInstance* card = NULL, int mode = MODE_PUTINTOPLAY, TargetChooser* tc = NULL,
|
int magicText(int id, Spell * spell, MTGCardInstance * card = NULL, int mode = MODE_PUTINTOPLAY, TargetChooser * tc = NULL, MTGGameZone * dest = NULL);
|
||||||
MTGGameZone* dest = NULL);
|
static int computeX(Spell * spell, MTGCardInstance * card);
|
||||||
static int computeX(Spell* spell, MTGCardInstance* card);
|
static int computeXX(Spell * spell, MTGCardInstance * card);
|
||||||
static int computeXX(Spell* spell, MTGCardInstance* card);
|
static MTGAbility * getCoreAbility(MTGAbility * a);
|
||||||
static MTGAbility* getCoreAbility(MTGAbility* a);
|
int destroyAllInPlay(TargetChooser * tc, int bury = 0);
|
||||||
int destroyAllInPlay(TargetChooser* tc, int bury = 0);
|
int moveAll(TargetChooser * tc, string destinationZone);
|
||||||
int moveAll(TargetChooser* tc, string destinationZone);
|
int damageAll(TargetChooser * tc, int damage);
|
||||||
int damageAll(TargetChooser* tc, int damage);
|
int TapAll(TargetChooser * tc);
|
||||||
int TapAll(TargetChooser* tc);
|
int UntapAll(TargetChooser * tc);
|
||||||
int UntapAll(TargetChooser* tc);
|
void addAbilities(int _id, Spell * spell);
|
||||||
void addAbilities(int _id, Spell* spell);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ActivatedAbilityTP: public ActivatedAbility
|
|
||||||
{
|
class ActivatedAbilityTP:public ActivatedAbility{
|
||||||
public:
|
public:
|
||||||
int who;
|
int who;
|
||||||
ActivatedAbilityTP(int id, MTGCardInstance* card, Targetable* _target = NULL, ManaCost* cost = NULL, int doTap = 0, int who =
|
ActivatedAbilityTP(int id, MTGCardInstance * card, Targetable * _target = NULL, ManaCost * cost=NULL, int doTap = 0, int who = TargetChooser::UNSET);
|
||||||
TargetChooser::UNSET);
|
Targetable * getTarget();
|
||||||
Targetable* getTarget();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class AManaProducer: public ActivatedAbilityTP
|
class AManaProducer: public ActivatedAbilityTP{
|
||||||
{
|
protected:
|
||||||
protected:
|
|
||||||
|
|
||||||
string menutext;
|
|
||||||
Player* controller;
|
|
||||||
|
|
||||||
public:
|
string menutext;
|
||||||
ManaCost* output;
|
Player * controller;
|
||||||
int tap;
|
|
||||||
AManaProducer(int id, MTGCardInstance* card, Targetable* t, ManaCost* _output, ManaCost* _cost = NULL, int doTap = 1, int who = TargetChooser::UNSET);
|
public:
|
||||||
int isReactingToClick(MTGCardInstance* _card, ManaCost* mana = NULL);
|
ManaCost * output;
|
||||||
int resolve();
|
int tap;
|
||||||
int reactToClick(MTGCardInstance* _card);
|
AManaProducer(int id, MTGCardInstance * card, Targetable * t, ManaCost * _output, ManaCost * _cost = NULL, int doTap = 1, int who = TargetChooser::UNSET );
|
||||||
const char* getMenuText();
|
int isReactingToClick(MTGCardInstance * _card, ManaCost * mana = NULL);
|
||||||
~AManaProducer();
|
int resolve();
|
||||||
virtual AManaProducer* clone() const;
|
int reactToClick(MTGCardInstance * _card);
|
||||||
|
const char * getMenuText();
|
||||||
|
~AManaProducer();
|
||||||
|
virtual AManaProducer * clone() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#include "MTGCardInstance.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "Damage.h"
|
#include "Damage.h"
|
||||||
#include "Targetable.h"
|
#include "Targetable.h"
|
||||||
|
|
||||||
|
|
||||||
class MTGCardInstance;
|
class MTGCardInstance;
|
||||||
class MTGPlayerCards;
|
class MTGPlayerCards;
|
||||||
class MTGAbility;
|
class MTGAbility;
|
||||||
@@ -23,150 +24,172 @@ struct Pos;
|
|||||||
#include <list>
|
#include <list>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
class MTGCardInstance: public CardPrimitive, public MTGCard, public Damageable
|
class MTGCardInstance: public CardPrimitive, public MTGCard, public Damageable {
|
||||||
{
|
protected:
|
||||||
protected:
|
int untapping;
|
||||||
int untapping;
|
int nb_damages;
|
||||||
int nb_damages;
|
string sample;
|
||||||
string sample;
|
int tapped;
|
||||||
int tapped;
|
int lifeOrig;
|
||||||
|
MTGPlayerCards * belongs_to;
|
||||||
int lifeOrig;
|
MTGCardInstance * getNextPartner();
|
||||||
MTGPlayerCards * belongs_to;
|
void initMTGCI();
|
||||||
MTGCardInstance * getNextPartner();
|
int addBlocker(MTGCardInstance * c);
|
||||||
void initMTGCI();
|
int removeBlocker(MTGCardInstance * c);
|
||||||
|
int init();
|
||||||
|
public:
|
||||||
|
int setAttacker(int value);
|
||||||
int setDefenser(MTGCardInstance * c);
|
int setDefenser(MTGCardInstance * c);
|
||||||
int addBlocker(MTGCardInstance * c);
|
MTGGameZone * currentZone;
|
||||||
int removeBlocker(MTGCardInstance * c);
|
Pos* view;
|
||||||
int init();
|
int X;
|
||||||
public:
|
int XX;
|
||||||
int setAttacker(int value);
|
int alternateCostPaid[ManaCost::MANA_PAID_WITH_RETRACE + 1];
|
||||||
MTGGameZone * currentZone;
|
int paymenttype;
|
||||||
Pos* view;
|
int frozen;
|
||||||
int X;
|
int sunburst;
|
||||||
int XX;
|
int equipment;
|
||||||
int alternateCostPaid[ManaCost::MANA_PAID_WITH_RETRACE + 1];
|
int auras;
|
||||||
int paymenttype;
|
int reduxamount;
|
||||||
int frozen;
|
int flanked;
|
||||||
int sunburst;
|
int regenerateTokens;
|
||||||
int equipment;
|
int isToken;
|
||||||
int reduxamount;
|
int origpower;
|
||||||
int flanked;
|
int origtoughness;
|
||||||
int regenerateTokens;
|
int isMultiColored;
|
||||||
int isToken;
|
int isBlackAndWhite;
|
||||||
int stillInUse();
|
int isRedAndBlue;
|
||||||
int didattacked;
|
int isBlackAndGreen;
|
||||||
int didblocked;
|
int isBlueAndGreen;
|
||||||
int notblocked;
|
int isRedAndWhite;
|
||||||
int fresh;
|
int isLeveler;
|
||||||
int MaxLevelUp;
|
bool enchanted;
|
||||||
Player * lastController;
|
int CDenchanted;
|
||||||
MTGGameZone * getCurrentZone();
|
bool blinked;
|
||||||
MTGGameZone * previousZone;
|
bool isExtraCostTarget;
|
||||||
MTGCardInstance * previous;
|
bool morphed;
|
||||||
MTGCardInstance * next;
|
bool turningOver;
|
||||||
int doDamageTest;
|
bool isMorphed;
|
||||||
int summoningSickness;
|
bool isPhased;
|
||||||
// The recommended method to test for summoning Sickness !
|
bool isTempPhased;
|
||||||
int hasSummoningSickness();
|
int phasedTurn;
|
||||||
MTGCardInstance * changeController(Player * newcontroller);
|
bool graveEffects;
|
||||||
Player * owner;
|
bool exileEffects;
|
||||||
Counters * counters;
|
|
||||||
int typeAsTarget()
|
|
||||||
{
|
|
||||||
return TARGET_CARD;
|
|
||||||
}
|
|
||||||
const string getDisplayName() const;
|
|
||||||
MTGCardInstance * target;
|
|
||||||
|
|
||||||
//types
|
int stillInUse();
|
||||||
void addType(char * type_text);
|
int didattacked;
|
||||||
virtual void addType(int id);
|
int didblocked;
|
||||||
void setType(const char * type_text);
|
int notblocked;
|
||||||
void setSubtype(string value);
|
int fresh;
|
||||||
int removeType(string value, int removeAll = 0);
|
int MaxLevelUp;
|
||||||
int removeType(int value, int removeAll = 0);
|
Player * lastController;
|
||||||
|
MTGGameZone * getCurrentZone();
|
||||||
|
MTGGameZone * previousZone;
|
||||||
|
MTGCardInstance * previous;
|
||||||
|
MTGCardInstance * next;
|
||||||
|
int doDamageTest;
|
||||||
|
int summoningSickness;
|
||||||
|
// The recommended method to test for summoning Sickness !
|
||||||
|
int hasSummoningSickness();
|
||||||
|
MTGCardInstance * changeController(Player * newcontroller);
|
||||||
|
Player * owner;
|
||||||
|
Counters * counters;
|
||||||
|
int typeAsTarget(){return TARGET_CARD;}
|
||||||
|
const string getDisplayName() const;
|
||||||
|
MTGCardInstance * target;
|
||||||
|
MTGCardInstance * imprint;
|
||||||
|
|
||||||
//dangerranking is a hint to Ai which creatures are the ones it should be targetting for effects.
|
|
||||||
int DangerRanking();
|
|
||||||
//Combat
|
|
||||||
bool blocked; //Blocked this turn or not?
|
|
||||||
MTGCardInstance * defenser;
|
|
||||||
list<MTGCardInstance *> blockers;
|
|
||||||
int attacker;
|
|
||||||
int toggleDefenser(MTGCardInstance * opponent);
|
|
||||||
int raiseBlockerRankOrder(MTGCardInstance * blocker);
|
|
||||||
|
|
||||||
//Returns rank of the card in blockers if it is a blocker of this (starting at 1), 0 otherwise
|
//types
|
||||||
int getDefenserRank(MTGCardInstance * blocker);
|
void addType(char * type_text);
|
||||||
int toggleAttacker();
|
virtual void addType(int id);
|
||||||
MTGCardInstance * banding; // If belongs to a band when attacking
|
void setType(const char * type_text);
|
||||||
int canBlock();
|
void setSubtype( string value);
|
||||||
int canBlock(MTGCardInstance * opponent);
|
int removeType(string value, int removeAll = 0);
|
||||||
int canAttack();
|
int removeType(int value, int removeAll = 0);
|
||||||
int isAttacker();
|
|
||||||
MTGCardInstance * isDefenser();
|
|
||||||
int initAttackersDefensers();
|
|
||||||
MTGCardInstance * getNextOpponent(MTGCardInstance * previous = NULL);
|
|
||||||
int nbOpponents();
|
|
||||||
int stepPower(CombatStep step);
|
|
||||||
int afterDamage();
|
|
||||||
int has(int ability);
|
|
||||||
int cleanup();
|
|
||||||
|
|
||||||
MTGCard * model;
|
//dangerranking is a hint to Ai which creatures are the ones it should be targetting for effects.
|
||||||
MTGCardInstance();
|
int DangerRanking();
|
||||||
MTGCardInstance(MTGCard * card, MTGPlayerCards * _belongs_to);
|
//Combat
|
||||||
int regenerate();
|
bool blocked; //Blocked this turn or not?
|
||||||
int triggerRegenerate();
|
MTGCardInstance * defenser;
|
||||||
Player * controller();
|
list<MTGCardInstance *>blockers;
|
||||||
|
int attacker;
|
||||||
|
int toggleDefenser(MTGCardInstance * opponent);
|
||||||
|
int raiseBlockerRankOrder(MTGCardInstance * blocker);
|
||||||
|
|
||||||
virtual ~MTGCardInstance();
|
//Returns rank of the card in blockers if it is a blocker of this (starting at 1), 0 otherwise
|
||||||
int bury();
|
int getDefenserRank(MTGCardInstance * blocker);
|
||||||
int destroy();
|
int toggleAttacker();
|
||||||
|
MTGCardInstance * banding; // If belongs to a band when attacking
|
||||||
|
int canBlock();
|
||||||
|
int canBlock(MTGCardInstance * opponent);
|
||||||
|
int canAttack();
|
||||||
|
int isAttacker();
|
||||||
|
MTGCardInstance * isDefenser();
|
||||||
|
int initAttackersDefensers();
|
||||||
|
MTGCardInstance * getNextOpponent(MTGCardInstance * previous=NULL);
|
||||||
|
int nbOpponents();
|
||||||
|
int stepPower(CombatStep step);
|
||||||
|
int afterDamage();
|
||||||
|
int has(int ability);
|
||||||
|
int cleanup();
|
||||||
|
|
||||||
int addToToughness(int value);
|
MTGCard * model;
|
||||||
int setToughness(int value);
|
MTGCardInstance();
|
||||||
|
MTGCardInstance(MTGCard * card, MTGPlayerCards * _belongs_to);
|
||||||
|
int regenerate();
|
||||||
|
int triggerRegenerate();
|
||||||
|
Player * controller();
|
||||||
|
|
||||||
vector<TargetChooser *> protections;
|
virtual ~MTGCardInstance();
|
||||||
int addProtection(TargetChooser * tc);
|
int bury();
|
||||||
int removeProtection(TargetChooser *tc, int erase = 0);
|
int destroy();
|
||||||
int protectedAgainst(MTGCardInstance * card);
|
|
||||||
|
|
||||||
vector<TargetChooser *> cantBeBlockedBys;
|
|
||||||
int addCantBeBlockedBy(TargetChooser * tc);
|
|
||||||
int removeCantBeBlockedBy(TargetChooser *tc, int erase = 0);
|
|
||||||
int cantBeBlockedBy(MTGCardInstance * card);
|
|
||||||
|
|
||||||
void copy(MTGCardInstance * card);
|
int addToToughness(int value);
|
||||||
|
int setToughness(int value);
|
||||||
|
|
||||||
void setUntapping();
|
vector<TargetChooser *>protections;
|
||||||
int isUntapping();
|
int addProtection(TargetChooser * tc);
|
||||||
int isTapped();
|
int removeProtection(TargetChooser *tc, int erase = 0);
|
||||||
void untap();
|
int protectedAgainst(MTGCardInstance * card);
|
||||||
void tap();
|
|
||||||
void attemptUntap();
|
|
||||||
|
|
||||||
void eventattacked();
|
vector<TargetChooser *>cantBeBlockedBys;
|
||||||
void eventattackedAlone();
|
int addCantBeBlockedBy(TargetChooser * tc);
|
||||||
void eventattackednotblocked();
|
int removeCantBeBlockedBy(TargetChooser *tc, int erase = 0);
|
||||||
void eventattackedblocked();
|
int cantBeBlockedBy(MTGCardInstance * card);
|
||||||
void eventblocked();
|
|
||||||
|
|
||||||
int isInPlay();
|
void copy(MTGCardInstance * card);
|
||||||
JSample * getSample();
|
|
||||||
|
|
||||||
JQuad * getIcon();
|
void setUntapping();
|
||||||
|
int isUntapping();
|
||||||
|
int isTapped();
|
||||||
|
void untap();
|
||||||
|
void tap();
|
||||||
|
void attemptUntap();
|
||||||
|
|
||||||
ostream& toString(ostream&) const;
|
void eventattacked();
|
||||||
|
void eventattackedAlone();
|
||||||
|
void eventattackednotblocked();
|
||||||
|
void eventattackedblocked();
|
||||||
|
void eventblocked();
|
||||||
|
|
||||||
static MTGCardInstance AnyCard;
|
int isInPlay();
|
||||||
static MTGCardInstance NoCard;
|
JSample * getSample();
|
||||||
|
|
||||||
static MTGCardInstance ExtraRules[2];
|
JQuad * getIcon();
|
||||||
|
|
||||||
|
ostream& toString(ostream&) const;
|
||||||
|
|
||||||
|
static MTGCardInstance AnyCard;
|
||||||
|
static MTGCardInstance NoCard;
|
||||||
|
|
||||||
|
static MTGCardInstance ExtraRules[2];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ostream& operator<<(ostream&, const MTGCardInstance&);
|
ostream& operator<<(ostream&, const MTGCardInstance&);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -9,216 +9,238 @@ const float DEFAULT_TEXT_FONT_SCALE = 1.0f;
|
|||||||
using std::string;
|
using std::string;
|
||||||
class Constants
|
class Constants
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Exception Codes
|
// Exception Codes
|
||||||
|
|
||||||
/* Exception codes */
|
/* Exception codes */
|
||||||
const static int PARSER_FAILED_INSTANTIATION = 1000;
|
const static int PARSER_FAILED_INSTANTIATION = 1000;
|
||||||
const static int PARSER_KEYWORD_NOT_MATCHED = 2000;
|
const static int PARSER_KEYWORD_NOT_MATCHED = 2000;
|
||||||
const static int PARSER_INVALID_KEYWORD = 3000;
|
const static int PARSER_INVALID_KEYWORD = 3000;
|
||||||
|
|
||||||
// color constants
|
|
||||||
static const string kManaColorless;
|
|
||||||
static const string kManaGreen;
|
|
||||||
static const string kManaBlue;
|
|
||||||
static const string kManaRed;
|
|
||||||
static const string kManaBlack;
|
|
||||||
static const string kManaWhite;
|
|
||||||
|
|
||||||
// alternative costs constants
|
// color constants
|
||||||
|
static const string kManaColorless;
|
||||||
|
static const string kManaGreen;
|
||||||
|
static const string kManaBlue;
|
||||||
|
static const string kManaRed;
|
||||||
|
static const string kManaBlack;
|
||||||
|
static const string kManaWhite;
|
||||||
|
|
||||||
static const string kAlternativeKeyword;
|
// alternative costs constants
|
||||||
static const string kBuyBackKeyword;
|
|
||||||
static const string kFlashBackKeyword;
|
|
||||||
static const string kRetraceKeyword;
|
|
||||||
static const string kKickerKeyword;
|
|
||||||
|
|
||||||
// used for deck statistics
|
static const string kAlternativeKeyword;
|
||||||
static const int STATS_FOR_TURNS = 8;
|
static const string kBuyBackKeyword;
|
||||||
static const int STATS_MAX_MANA_COST = 9;
|
static const string kFlashBackKeyword;
|
||||||
|
static const string kRetraceKeyword;
|
||||||
|
static const string kKickerKeyword;
|
||||||
|
static const string kMorphKeyword;
|
||||||
|
|
||||||
enum
|
// used for deck statistics
|
||||||
{
|
static const int STATS_FOR_TURNS = 8;
|
||||||
MTG_COLOR_ARTIFACT = 0,
|
static const int STATS_MAX_MANA_COST = 9;
|
||||||
MTG_COLOR_GREEN = 1,
|
|
||||||
MTG_COLOR_BLUE = 2,
|
|
||||||
MTG_COLOR_RED = 3,
|
|
||||||
MTG_COLOR_BLACK = 4,
|
|
||||||
MTG_COLOR_WHITE = 5,
|
|
||||||
MTG_COLOR_LAND = 6,
|
|
||||||
|
|
||||||
MTG_NB_COLORS = 7,
|
enum
|
||||||
|
{
|
||||||
|
MTG_COLOR_ARTIFACT = 0,
|
||||||
|
MTG_COLOR_GREEN = 1,
|
||||||
|
MTG_COLOR_BLUE = 2,
|
||||||
|
MTG_COLOR_RED = 3,
|
||||||
|
MTG_COLOR_BLACK = 4,
|
||||||
|
MTG_COLOR_WHITE = 5,
|
||||||
|
MTG_COLOR_LAND = 6,
|
||||||
|
|
||||||
MTG_UNCOLORED = 0,
|
MTG_NB_COLORS = 7,
|
||||||
MTG_FOREST = 1,
|
|
||||||
MTG_ISLAND = 2,
|
|
||||||
MTG_MOUNTAIN = 3,
|
|
||||||
MTG_SWAMP = 4,
|
|
||||||
MTG_PLAIN = 5,
|
|
||||||
|
|
||||||
MTG_TYPE_CREATURE = 10,
|
|
||||||
MTG_TYPE_ARTIFACT = 11,
|
|
||||||
MTG_TYPE_ENCHANTMENT = 12,
|
|
||||||
MTG_TYPE_SORCERY = 13,
|
|
||||||
MTG_TYPE_LAND = 14,
|
|
||||||
MTG_TYPE_INSTANT = 15,
|
|
||||||
|
|
||||||
MTG_PHASE_BEFORE_BEGIN = 0,
|
MTG_UNCOLORED = 0,
|
||||||
MTG_PHASE_UNTAP = 1,
|
MTG_FOREST = 1,
|
||||||
MTG_PHASE_UPKEEP = 2,
|
MTG_ISLAND = 2,
|
||||||
MTG_PHASE_DRAW = 3,
|
MTG_MOUNTAIN = 3,
|
||||||
MTG_PHASE_FIRSTMAIN = 4,
|
MTG_SWAMP = 4,
|
||||||
MTG_PHASE_COMBATBEGIN = 5,
|
MTG_PLAIN = 5,
|
||||||
MTG_PHASE_COMBATATTACKERS = 6,
|
|
||||||
MTG_PHASE_COMBATBLOCKERS = 7,
|
|
||||||
MTG_PHASE_COMBATDAMAGE = 8,
|
|
||||||
MTG_PHASE_COMBATEND = 9,
|
|
||||||
MTG_PHASE_SECONDMAIN = 10,
|
|
||||||
MTG_PHASE_ENDOFTURN = 11,
|
|
||||||
MTG_PHASE_EOT = 11,
|
|
||||||
MTG_PHASE_CLEANUP = 12,
|
|
||||||
MTG_PHASE_AFTER_EOT = 13,
|
|
||||||
NB_MTG_PHASES = 14,
|
|
||||||
|
|
||||||
TRAMPLE = 0,
|
|
||||||
FORESTWALK = 1,
|
|
||||||
ISLANDWALK = 2,
|
|
||||||
MOUNTAINWALK = 3,
|
|
||||||
SWAMPWALK = 4,
|
|
||||||
PLAINSWALK = 5,
|
|
||||||
FLYING = 6,
|
|
||||||
FIRSTSTRIKE = 7,
|
|
||||||
DOUBLESTRIKE = 8,
|
|
||||||
FEAR = 9,
|
|
||||||
FLASH = 10,
|
|
||||||
HASTE = 11,
|
|
||||||
LIFELINK = 12,
|
|
||||||
REACH = 13,
|
|
||||||
SHROUD = 14,
|
|
||||||
VIGILANCE = 15,
|
|
||||||
DEFENSER = 16,
|
|
||||||
DEFENDER = 16,
|
|
||||||
BANDING = 17,
|
|
||||||
PROTECTIONGREEN = 18,
|
|
||||||
PROTECTIONBLUE = 19,
|
|
||||||
PROTECTIONRED = 20,
|
|
||||||
PROTECTIONBLACK = 21,
|
|
||||||
PROTECTIONWHITE = 22,
|
|
||||||
UNBLOCKABLE = 23,
|
|
||||||
WITHER = 24,
|
|
||||||
PERSIST = 25,
|
|
||||||
RETRACE = 26,
|
|
||||||
EXALTED = 27,
|
|
||||||
NOFIZZLE = 28,
|
|
||||||
SHADOW = 29,
|
|
||||||
REACHSHADOW = 30,
|
|
||||||
FORESTHOME = 31,
|
|
||||||
ISLANDHOME = 32,
|
|
||||||
MOUNTAINHOME = 33,
|
|
||||||
SWAMPHOME = 34,
|
|
||||||
PLAINSHOME = 35,
|
|
||||||
CLOUD = 36,
|
|
||||||
CANTATTACK = 37,
|
|
||||||
MUSTATTACK = 38,
|
|
||||||
CANTBLOCK = 39,
|
|
||||||
DOESNOTUNTAP = 40,
|
|
||||||
OPPONENTSHROUD = 41,
|
|
||||||
INDESTRUCTIBLE = 42,
|
|
||||||
INTIMIDATE = 43,
|
|
||||||
DEATHTOUCH = 44,
|
|
||||||
HORSEMANSHIP = 45,
|
|
||||||
CANTREGEN = 46,
|
|
||||||
ONEBLOCKER = 47,
|
|
||||||
INFECT = 48,
|
|
||||||
POISONTOXIC = 49,
|
|
||||||
POISONTWOTOXIC = 50,
|
|
||||||
POISONTHREETOXIC = 51,
|
|
||||||
PHANTOM = 52,
|
|
||||||
WILTING = 53,
|
|
||||||
VIGOR = 54,
|
|
||||||
CHANGELING = 55,
|
|
||||||
ABSORB = 56,//this need to be coded for players too "If a source would deal damage"
|
|
||||||
TREASON = 57,
|
|
||||||
UNEARTH = 58,
|
|
||||||
CANTLOSE = 59,
|
|
||||||
CANTLIFELOSE = 60,
|
|
||||||
CANTMILLLOSE = 61,
|
|
||||||
CANTCASTCREATURE = 62,
|
|
||||||
CANTCAST = 63,
|
|
||||||
CANTCASTTWO = 64,
|
|
||||||
STORM = 65,
|
|
||||||
BOTHCANTCAST = 66,
|
|
||||||
BOTHNOCREATURE = 67,
|
|
||||||
ONLYONEBOTH = 68,
|
|
||||||
AFFINITYARTIFACTS = 69,
|
|
||||||
AFFINITYPLAINS = 70,
|
|
||||||
AFFINITYFOREST = 71,
|
|
||||||
AFFINITYISLAND = 72,
|
|
||||||
AFFINITYMOUNTAIN = 73,
|
|
||||||
AFFINITYSWAMP = 74,
|
|
||||||
AFFINITYGREENCREATURES = 75,
|
|
||||||
CANTWIN = 76,
|
|
||||||
NOMAXHAND = 77,
|
|
||||||
LEYLINE = 78,
|
|
||||||
PLAYERSHROUD = 79,
|
|
||||||
CONTROLLERSHROUD = 80,
|
|
||||||
SUNBURST = 81,
|
|
||||||
FLANKING = 82,
|
|
||||||
EXILEDEATH = 83,
|
|
||||||
|
|
||||||
NB_BASIC_ABILITIES = 84,
|
MTG_TYPE_CREATURE = 10,
|
||||||
|
MTG_TYPE_ARTIFACT = 11,
|
||||||
|
MTG_TYPE_ENCHANTMENT = 12,
|
||||||
|
MTG_TYPE_SORCERY = 13,
|
||||||
|
MTG_TYPE_LAND = 14,
|
||||||
|
MTG_TYPE_INSTANT = 15,
|
||||||
|
|
||||||
RARITY_S = 'S', //Special Rarity
|
|
||||||
RARITY_M = 'M', //Mythics
|
|
||||||
RARITY_R = 'R', //Rares
|
|
||||||
RARITY_U = 'U', //Uncommons
|
|
||||||
RARITY_C = 'C', //Commons
|
|
||||||
RARITY_L = 'L', //Lands
|
|
||||||
RARITY_T = 'T', //Tokens
|
|
||||||
|
|
||||||
ECON_NORMAL = 0, //Options default to 0.
|
MTG_PHASE_BEFORE_BEGIN = 0,
|
||||||
ECON_HARD = 1,
|
MTG_PHASE_UNTAP = 1,
|
||||||
ECON_LUCK = 2,
|
MTG_PHASE_UPKEEP = 2,
|
||||||
ECON_EASY = 3,
|
MTG_PHASE_DRAW = 3,
|
||||||
|
MTG_PHASE_FIRSTMAIN = 4,
|
||||||
|
MTG_PHASE_COMBATBEGIN = 5,
|
||||||
|
MTG_PHASE_COMBATATTACKERS = 6,
|
||||||
|
MTG_PHASE_COMBATBLOCKERS = 7,
|
||||||
|
MTG_PHASE_COMBATDAMAGE = 8,
|
||||||
|
MTG_PHASE_COMBATEND = 9,
|
||||||
|
MTG_PHASE_SECONDMAIN = 10,
|
||||||
|
MTG_PHASE_ENDOFTURN = 11,
|
||||||
|
MTG_PHASE_CLEANUP = 12,
|
||||||
|
MTG_PHASE_AFTER_EOT = 13,
|
||||||
|
NB_MTG_PHASES = 14,
|
||||||
|
|
||||||
//Price for singles
|
TRAMPLE = 0,
|
||||||
PRICE_1M = 3000,
|
FORESTWALK = 1,
|
||||||
PRICE_1R = 500,
|
ISLANDWALK = 2,
|
||||||
PRICE_1S = 200,
|
MOUNTAINWALK = 3,
|
||||||
PRICE_1U = 100,
|
SWAMPWALK = 4,
|
||||||
PRICE_1C = 20,
|
PLAINSWALK = 5,
|
||||||
PRICE_1L = 5,
|
FLYING = 6,
|
||||||
|
FIRSTSTRIKE = 7,
|
||||||
|
DOUBLESTRIKE = 8,
|
||||||
|
FEAR = 9,
|
||||||
|
FLASH = 10,
|
||||||
|
HASTE = 11,
|
||||||
|
LIFELINK = 12,
|
||||||
|
REACH = 13,
|
||||||
|
SHROUD = 14,
|
||||||
|
VIGILANCE = 15,
|
||||||
|
DEFENSER = 16,
|
||||||
|
DEFENDER = 16,
|
||||||
|
BANDING = 17,
|
||||||
|
PROTECTIONGREEN = 18,
|
||||||
|
PROTECTIONBLUE = 19,
|
||||||
|
PROTECTIONRED = 20,
|
||||||
|
PROTECTIONBLACK = 21,
|
||||||
|
PROTECTIONWHITE = 22,
|
||||||
|
UNBLOCKABLE = 23,
|
||||||
|
WITHER = 24,
|
||||||
|
PERSIST = 25,
|
||||||
|
RETRACE = 26,
|
||||||
|
EXALTED = 27,
|
||||||
|
NOFIZZLE = 28,
|
||||||
|
SHADOW = 29,
|
||||||
|
REACHSHADOW = 30,
|
||||||
|
FORESTHOME = 31,
|
||||||
|
ISLANDHOME = 32,
|
||||||
|
MOUNTAINHOME = 33,
|
||||||
|
SWAMPHOME = 34,
|
||||||
|
PLAINSHOME = 35,
|
||||||
|
CLOUD = 36,
|
||||||
|
CANTATTACK = 37,
|
||||||
|
MUSTATTACK = 38,
|
||||||
|
CANTBLOCK = 39,
|
||||||
|
DOESNOTUNTAP = 40,
|
||||||
|
OPPONENTSHROUD = 41,
|
||||||
|
INDESTRUCTIBLE = 42,
|
||||||
|
INTIMIDATE = 43,
|
||||||
|
DEATHTOUCH = 44,
|
||||||
|
HORSEMANSHIP = 45,
|
||||||
|
CANTREGEN = 46,
|
||||||
|
ONEBLOCKER = 47,
|
||||||
|
INFECT = 48,
|
||||||
|
POISONTOXIC = 49,
|
||||||
|
POISONTWOTOXIC = 50,
|
||||||
|
POISONTHREETOXIC = 51,
|
||||||
|
PHANTOM = 52,
|
||||||
|
WILTING = 53,
|
||||||
|
VIGOR = 54,
|
||||||
|
CHANGELING = 55,
|
||||||
|
ABSORB = 56,//this need to be coded for players too "If a source would deal damage"
|
||||||
|
TREASON = 57,
|
||||||
|
UNEARTH = 58,
|
||||||
|
CANTLOSE = 59,
|
||||||
|
CANTLIFELOSE = 60,
|
||||||
|
CANTMILLLOSE = 61,
|
||||||
|
CANTCASTCREATURE = 62,
|
||||||
|
CANTCAST = 63,
|
||||||
|
CANTCASTTWO = 64,
|
||||||
|
STORM = 65,
|
||||||
|
BOTHCANTCAST = 66,
|
||||||
|
BOTHNOCREATURE = 67,
|
||||||
|
ONLYONEBOTH = 68,
|
||||||
|
AFFINITYARTIFACTS = 69,
|
||||||
|
AFFINITYPLAINS = 70,
|
||||||
|
AFFINITYFOREST = 71,
|
||||||
|
AFFINITYISLAND = 72,
|
||||||
|
AFFINITYMOUNTAIN = 73,
|
||||||
|
AFFINITYSWAMP = 74,
|
||||||
|
AFFINITYGREENCREATURES = 75,
|
||||||
|
CANTWIN = 76,
|
||||||
|
NOMAXHAND = 77,
|
||||||
|
LEYLINE = 78,
|
||||||
|
PLAYERSHROUD = 79,
|
||||||
|
CONTROLLERSHROUD = 80,
|
||||||
|
SUNBURST = 81,
|
||||||
|
FLANKING = 82,
|
||||||
|
EXILEDEATH = 83,
|
||||||
|
LEGENDARYWALK = 84,
|
||||||
|
DESERTWALK = 85,
|
||||||
|
SNOWFORESTWALK = 86,
|
||||||
|
SNOWPLAINSWALK = 87,
|
||||||
|
SNOWMOUNTAINWALK = 88,
|
||||||
|
SNOWISLANDWALK = 89,
|
||||||
|
SNOWSWAMPWALK = 90,
|
||||||
|
SNOWWALK = 91,
|
||||||
|
NONBASICWALK = 92,
|
||||||
|
STRONG = 93,
|
||||||
|
WEAK = 94,
|
||||||
|
PHASING = 95,
|
||||||
|
|
||||||
//Price in booster
|
NB_BASIC_ABILITIES = 96,
|
||||||
PRICE_BOOSTER = 700,
|
|
||||||
PRICE_MIXED_BOOSTER = 800,
|
|
||||||
CHANCE_CUSTOM_PACK = 15,
|
|
||||||
CHANCE_PURE_OVERRIDE = 50,
|
|
||||||
CHANCE_MIXED_OVERRIDE = 25,
|
|
||||||
|
|
||||||
GRADE_SUPPORTED = 0,
|
|
||||||
GRADE_BORDERLINE = 1,
|
|
||||||
GRADE_UNOFFICIAL = 2,
|
|
||||||
GRADE_CRAPPY = 3,
|
|
||||||
GRADE_UNSUPPORTED = 4,
|
|
||||||
GRADE_DANGEROUS = 5,
|
|
||||||
|
|
||||||
ASKIP_NONE = 0,
|
RARITY_S = 'S', //Special Rarity
|
||||||
ASKIP_SAFE = 1,
|
RARITY_M = 'M', //Mythics
|
||||||
ASKIP_FULL = 2,
|
RARITY_R = 'R', //Rares
|
||||||
};
|
RARITY_U = 'U', //Uncommons
|
||||||
|
RARITY_C = 'C', //Commons
|
||||||
|
RARITY_L = 'L', //Lands
|
||||||
|
RARITY_T = 'T', //Tokens
|
||||||
|
|
||||||
static char MTGColorChars[];
|
ECON_NORMAL = 0, //Options default to 0.
|
||||||
static const char* MTGColorStrings[];
|
ECON_HARD = 1,
|
||||||
static int _r[], _g[], _b[];
|
ECON_LUCK = 2,
|
||||||
|
ECON_EASY = 3,
|
||||||
|
|
||||||
static map<string, int> MTGBasicAbilitiesMap;
|
//Price for singles
|
||||||
static const char* MTGBasicAbilities[];
|
PRICE_1M = 3000,
|
||||||
static const char* MTGPhaseNames[];
|
PRICE_1R = 500,
|
||||||
static const char* MTGPhaseCodeNames[];
|
PRICE_1S = 200,
|
||||||
|
PRICE_1U = 100,
|
||||||
|
PRICE_1C = 20,
|
||||||
|
PRICE_1L = 5,
|
||||||
|
|
||||||
static int GetBasicAbilityIndex(string mtgAbility);
|
//Price in booster
|
||||||
static int GetColorStringIndex(string mtgColor);
|
PRICE_BOOSTER = 700,
|
||||||
|
PRICE_MIXED_BOOSTER = 800,
|
||||||
|
CHANCE_CUSTOM_PACK = 15,
|
||||||
|
CHANCE_PURE_OVERRIDE = 50,
|
||||||
|
CHANCE_MIXED_OVERRIDE = 25,
|
||||||
|
|
||||||
|
GRADE_SUPPORTED = 0,
|
||||||
|
GRADE_BORDERLINE = 1,
|
||||||
|
GRADE_UNOFFICIAL = 2,
|
||||||
|
GRADE_CRAPPY = 3,
|
||||||
|
GRADE_UNSUPPORTED = 4,
|
||||||
|
GRADE_DANGEROUS = 5,
|
||||||
|
|
||||||
|
ASKIP_NONE=0,
|
||||||
|
ASKIP_SAFE=1,
|
||||||
|
ASKIP_FULL=2,
|
||||||
|
|
||||||
|
WHO_P=0,
|
||||||
|
WHO_O=1,
|
||||||
|
WHO_R=2,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
static char MTGColorChars[];
|
||||||
|
static const char* MTGColorStrings[];
|
||||||
|
static int _r[], _g[], _b[];
|
||||||
|
|
||||||
|
static map<string,int> MTGBasicAbilitiesMap;
|
||||||
|
static const char* MTGBasicAbilities[];
|
||||||
|
static const char* MTGPhaseNames[];
|
||||||
|
static const char* MTGPhaseCodeNames[];
|
||||||
|
|
||||||
|
static int GetBasicAbilityIndex(string mtgAbility);
|
||||||
|
static int GetColorStringIndex(string mtgColor);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+135
-158
@@ -14,191 +14,168 @@ class MTGDeck;
|
|||||||
class MTGCardInstance;
|
class MTGCardInstance;
|
||||||
class Player;
|
class Player;
|
||||||
|
|
||||||
class MTGGameZone
|
class MTGGameZone {
|
||||||
{
|
protected:
|
||||||
protected:
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum
|
enum{
|
||||||
{
|
ALL_ZONES = -1,
|
||||||
ALL_ZONES = -1,
|
|
||||||
|
|
||||||
MY_GRAVEYARD = 11,
|
MY_GRAVEYARD = 11,
|
||||||
OPPONENT_GRAVEYARD = 12,
|
OPPONENT_GRAVEYARD = 12,
|
||||||
TARGET_OWNER_GRAVEYARD = 13,
|
TARGET_OWNER_GRAVEYARD = 13,
|
||||||
TARGET_CONTROLLER_GRAVEYARD = 14,
|
TARGET_CONTROLLER_GRAVEYARD = 14,
|
||||||
GRAVEYARD = 15,
|
GRAVEYARD = 15,
|
||||||
OWNER_GRAVEYARD = 16,
|
OWNER_GRAVEYARD = 16,
|
||||||
|
|
||||||
MY_BATTLEFIELD = 21,
|
MY_BATTLEFIELD = 21,
|
||||||
OPPONENT_BATTLEFIELD = 22,
|
OPPONENT_BATTLEFIELD = 22,
|
||||||
TARGET_OWNER_BATTLEFIELD = 23,
|
TARGET_OWNER_BATTLEFIELD = 23,
|
||||||
TARGET_CONTROLLER_BATTLEFIELD = 24,
|
TARGET_CONTROLLER_BATTLEFIELD = 24,
|
||||||
BATTLEFIELD = 25,
|
BATTLEFIELD = 25,
|
||||||
OWNER_BATTLEFIELD = 26,
|
OWNER_BATTLEFIELD = 26,
|
||||||
|
|
||||||
MY_HAND = 31,
|
MY_HAND = 31,
|
||||||
OPPONENT_HAND = 32,
|
OPPONENT_HAND = 32,
|
||||||
TARGET_OWNER_HAND = 33,
|
TARGET_OWNER_HAND = 33,
|
||||||
TARGET_CONTROLLER_HAND = 34,
|
TARGET_CONTROLLER_HAND = 34,
|
||||||
HAND = 35,
|
HAND = 35,
|
||||||
OWNER_HAND = 36,
|
OWNER_HAND = 36,
|
||||||
|
|
||||||
MY_EXILE = 41,
|
MY_EXILE = 41,
|
||||||
OPPONENT_EXILE = 42,
|
OPPONENT_EXILE = 42,
|
||||||
TARGET_OWNER_EXILE = 43,
|
TARGET_OWNER_EXILE = 43,
|
||||||
TARGET_CONTROLLER_EXILE = 44,
|
TARGET_CONTROLLER_EXILE = 44,
|
||||||
EXILE = 45,
|
EXILE = 45,
|
||||||
OWNER_EXILE = 46,
|
OWNER_EXILE = 46,
|
||||||
|
|
||||||
MY_LIBRARY = 51,
|
MY_LIBRARY = 51,
|
||||||
OPPONENT_LIBRARY = 52,
|
OPPONENT_LIBRARY = 52,
|
||||||
TARGET_OWNER_LIBRARY = 53,
|
TARGET_OWNER_LIBRARY = 53,
|
||||||
TARGET_CONTROLLER_LIBRARY = 54,
|
TARGET_CONTROLLER_LIBRARY = 54,
|
||||||
LIBRARY = 55,
|
LIBRARY = 55,
|
||||||
OWNER_LIBRARY = 56,
|
OWNER_LIBRARY = 56,
|
||||||
|
|
||||||
MY_STACK = 61,
|
MY_STACK = 61,
|
||||||
OPPONENT_STACK = 62,
|
OPPONENT_STACK = 62,
|
||||||
TARGET_OWNER_STACK = 63,
|
TARGET_OWNER_STACK = 63,
|
||||||
TARGET_CONTROLLER_STACK = 64,
|
TARGET_CONTROLLER_STACK = 64,
|
||||||
STACK = 65,
|
STACK = 65,
|
||||||
OWNER_STACK = 66,
|
OWNER_STACK = 66,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Player * owner;
|
Player * owner;
|
||||||
//Both cards and cardsMap contain the cards of a zone. The long term objective is to get rid of the array
|
//Both cards and cardsMap contain the cards of a zone. The long term objective is to get rid of the array
|
||||||
vector<MTGCardInstance *> cards; //[MTG_MAX_PLAYER_CARDS];
|
vector<MTGCardInstance *> cards; //[MTG_MAX_PLAYER_CARDS];
|
||||||
map<MTGCardInstance *, int> cardsMap;
|
map<MTGCardInstance *,int> cardsMap;
|
||||||
int nb_cards;
|
int nb_cards;
|
||||||
MTGGameZone();
|
MTGGameZone();
|
||||||
~MTGGameZone();
|
~MTGGameZone();
|
||||||
void shuffle();
|
void shuffle();
|
||||||
void addCard(MTGCardInstance * card);
|
void addCard(MTGCardInstance * card);
|
||||||
void debugPrint();
|
void debugPrint();
|
||||||
MTGCardInstance * removeCard(MTGCardInstance * card, int createCopy = 1);
|
MTGCardInstance * removeCard(MTGCardInstance * card, int createCopy = 1);
|
||||||
MTGCardInstance * hasCard(MTGCardInstance * card);
|
MTGCardInstance * hasCard(MTGCardInstance * card);
|
||||||
void cleanupPhase();
|
void cleanupPhase();
|
||||||
int countByType(const char * value);
|
int countByType(const char * value);
|
||||||
MTGCardInstance * findByName(string name);
|
MTGCardInstance * findByName(string name);
|
||||||
int hasAbility(int ability); //returns 1 if one of the cards in the zone has the ability, 0 otherwise
|
int hasAbility(int ability); //returns 1 if one of the cards in the zone has the ability, 0 otherwise
|
||||||
int hasType(const char * value); //returns 1 if one of the cards in the zone has the type, 0 otherwise
|
int hasType(const char * value); //returns 1 if one of the cards in the zone has the type, 0 otherwise
|
||||||
int hasColor(int value); //returns 1 if one of the cards in the zone has the color, 0 otherwise
|
int hasSpecificType(const char * value,const char * secondvalue); //returns 1 if one of the cards in the zone has the type, 0 otherwise
|
||||||
int hasX();
|
int hasPrimaryType(const char * value,const char * secondvalue); //returns 1 if one of the cards in the zone has the type, 0 otherwise
|
||||||
void setOwner(Player * player);
|
int hasTypeButNotType(const char * value,const char * secondvalue); //returns 1 if one of the cards in the zone has the type, 0 otherwise
|
||||||
MTGCardInstance * lastCardDrawn;
|
int hasName(string value);
|
||||||
static MTGGameZone * stringToZone(string zoneName, MTGCardInstance * source, MTGCardInstance * target);
|
int hasColor(int value); //returns 1 if one of the cards in the zone has the color, 0 otherwise
|
||||||
static int zoneStringToId(string zoneName);
|
int hasX();
|
||||||
static MTGGameZone *intToZone(int zoneId, MTGCardInstance * source = NULL, MTGCardInstance * target = NULL);
|
void setOwner(Player * player);
|
||||||
bool needShuffle;
|
MTGCardInstance * lastCardDrawn;
|
||||||
virtual const char * getName()
|
static MTGGameZone * stringToZone(string zoneName, MTGCardInstance * source, MTGCardInstance * target);
|
||||||
{
|
static int zoneStringToId(string zoneName);
|
||||||
return "zone";
|
static MTGGameZone *intToZone(int zoneId, MTGCardInstance * source = NULL,MTGCardInstance * target = NULL);
|
||||||
}
|
bool needShuffle;
|
||||||
;
|
virtual const char * getName(){return "zone";};
|
||||||
virtual ostream& toString(ostream&) const;
|
virtual ostream& toString(ostream&) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MTGLibrary: public MTGGameZone
|
class MTGLibrary: public MTGGameZone {
|
||||||
{
|
public:
|
||||||
public:
|
void shuffleTopToBottom(int nbcards);
|
||||||
void shuffleTopToBottom(int nbcards);
|
virtual ostream& toString(ostream&) const;
|
||||||
virtual ostream& toString(ostream&) const;
|
const char * getName(){return "library";}
|
||||||
const char * getName()
|
|
||||||
{
|
|
||||||
return "library";
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class MTGGraveyard: public MTGGameZone
|
class MTGGraveyard: public MTGGameZone {
|
||||||
{
|
public:
|
||||||
public:
|
virtual ostream& toString(ostream&) const;
|
||||||
virtual ostream& toString(ostream&) const;
|
const char * getName(){return "graveyard";}
|
||||||
const char * getName()
|
|
||||||
{
|
|
||||||
return "graveyard";
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class MTGHand: public MTGGameZone
|
class MTGHand: public MTGGameZone {
|
||||||
{
|
public:
|
||||||
public:
|
virtual ostream& toString(ostream&) const;
|
||||||
virtual ostream& toString(ostream&) const;
|
const char * getName(){return "hand";}
|
||||||
const char * getName()
|
|
||||||
{
|
|
||||||
return "hand";
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class MTGRemovedFromGame: public MTGGameZone
|
class MTGRemovedFromGame: public MTGGameZone {
|
||||||
{
|
public:
|
||||||
public:
|
virtual ostream& toString(ostream&) const;
|
||||||
virtual ostream& toString(ostream&) const;
|
const char * getName(){return "exile";}
|
||||||
const char * getName()
|
|
||||||
{
|
|
||||||
return "exile";
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class MTGStack: public MTGGameZone
|
class MTGStack: public MTGGameZone {
|
||||||
{
|
public:
|
||||||
public:
|
virtual ostream& toString(ostream&) const;
|
||||||
virtual ostream& toString(ostream&) const;
|
const char * getName(){return "stack";}
|
||||||
const char * getName()
|
|
||||||
{
|
|
||||||
return "stack";
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class MTGInPlay: public MTGGameZone
|
class MTGInPlay: public MTGGameZone {
|
||||||
{
|
public:
|
||||||
public:
|
void untapAll();
|
||||||
void untapAll();
|
MTGCardInstance * getNextAttacker(MTGCardInstance * previous);
|
||||||
MTGCardInstance * getNextAttacker(MTGCardInstance * previous);
|
virtual ostream& toString(ostream&) const;
|
||||||
virtual ostream& toString(ostream&) const;
|
const char * getName(){return "battlefield";}
|
||||||
const char * getName()
|
|
||||||
{
|
|
||||||
return "battlefield";
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class MTGPlayerCards
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
void init();
|
|
||||||
|
|
||||||
public:
|
class MTGPlayerCards {
|
||||||
MTGLibrary * library;
|
protected:
|
||||||
MTGGraveyard * graveyard;
|
void init();
|
||||||
MTGHand * hand;
|
|
||||||
MTGInPlay * inPlay;
|
|
||||||
MTGInPlay * battlefield; //alias to inPlay
|
|
||||||
|
|
||||||
MTGStack * stack;
|
public:
|
||||||
MTGRemovedFromGame * removedFromGame;
|
MTGLibrary * library;
|
||||||
MTGRemovedFromGame * exile; //alias to removedFromZone
|
MTGGraveyard * graveyard;
|
||||||
MTGGameZone * garbage;
|
MTGHand * hand;
|
||||||
MTGGameZone * temp;
|
MTGInPlay * inPlay;
|
||||||
|
MTGInPlay * battlefield; //alias to inPlay
|
||||||
|
|
||||||
MTGPlayerCards(int * idList, int idListSize);
|
MTGStack * stack;
|
||||||
MTGPlayerCards(MTGDeck * deck);
|
MTGRemovedFromGame * removedFromGame;
|
||||||
~MTGPlayerCards();
|
MTGRemovedFromGame * exile; //alias to removedFromZone
|
||||||
void initGame(int shuffle = 1, int draw = 1);
|
MTGGameZone * garbage;
|
||||||
void OptimizedHand(Player * who, int amount = 7, int lands = 3, int creatures = 0, int othercards = 4);
|
MTGGameZone * temp;
|
||||||
void setOwner(Player * player);
|
|
||||||
void discardRandom(MTGGameZone * from, MTGCardInstance * source);
|
MTGPlayerCards(int * idList, int idListSize);
|
||||||
void drawFromLibrary();
|
MTGPlayerCards(MTGDeck * deck);
|
||||||
void showHand();
|
~MTGPlayerCards();
|
||||||
void resetLibrary();
|
void initGame(int shuffle = 1, int draw = 1);
|
||||||
void initDeck(MTGDeck * deck);
|
void OptimizedHand(Player * who,int amount = 7,int lands = 3,int creatures = 0,int othercards = 4);
|
||||||
MTGCardInstance * putInGraveyard(MTGCardInstance * card);
|
void setOwner(Player * player);
|
||||||
MTGCardInstance * putInExile(MTGCardInstance * card);
|
void discardRandom(MTGGameZone * from,MTGCardInstance * source);
|
||||||
MTGCardInstance * putInLibrary(MTGCardInstance * card);
|
void drawFromLibrary();
|
||||||
MTGCardInstance * putInHand(MTGCardInstance * card);
|
void showHand();
|
||||||
MTGCardInstance * putInZone(MTGCardInstance * card, MTGGameZone * from, MTGGameZone * to);
|
void resetLibrary();
|
||||||
int isInPlay(MTGCardInstance * card);
|
void initDeck(MTGDeck * deck);
|
||||||
|
MTGCardInstance * putInGraveyard(MTGCardInstance * card);
|
||||||
|
MTGCardInstance * putInExile(MTGCardInstance * card);
|
||||||
|
MTGCardInstance * putInLibrary(MTGCardInstance * card);
|
||||||
|
MTGCardInstance * putInHand(MTGCardInstance * card);
|
||||||
|
MTGCardInstance * putInBattlefield(MTGCardInstance * card);
|
||||||
|
MTGCardInstance * putInZone(MTGCardInstance * card, MTGGameZone * from, MTGGameZone * to);
|
||||||
|
int isInPlay(MTGCardInstance * card);
|
||||||
|
int isInGrave(MTGCardInstance * card);
|
||||||
|
int isInZone(MTGCardInstance * card,MTGGameZone * zone);
|
||||||
};
|
};
|
||||||
|
|
||||||
ostream& operator<<(ostream&, const MTGGameZone&);
|
ostream& operator<<(ostream&, const MTGGameZone&);
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ public:
|
|||||||
OtherAbilitiesEventReceiver(int _id);
|
OtherAbilitiesEventReceiver(int _id);
|
||||||
OtherAbilitiesEventReceiver * clone() const;
|
OtherAbilitiesEventReceiver * clone() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MTGPutInPlayRule: public MTGAbility
|
class MTGPutInPlayRule: public MTGAbility
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -37,10 +36,11 @@ public:
|
|||||||
class MTGAlternativeCostRule: public MTGAbility
|
class MTGAlternativeCostRule: public MTGAbility
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
|
int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
|
||||||
int isReactingToClick(MTGCardInstance * card, ManaCost * mana, ManaCost *alternateManaCost);
|
int isReactingToClick(MTGCardInstance * card, ManaCost * mana, ManaCost *alternateManaCost);
|
||||||
|
|
||||||
int reactToClick(MTGCardInstance * card, ManaCost * alternateManaCost, MTGGameZone * originatingZone, int paymentType = ManaCost::MANA_PAID);
|
int reactToClick(MTGCardInstance * card, ManaCost * alternateManaCost, int paymentType = ManaCost::MANA_PAID);
|
||||||
int reactToClick(MTGCardInstance * card);
|
int reactToClick(MTGCardInstance * card);
|
||||||
|
|
||||||
int testDestroy();
|
int testDestroy();
|
||||||
@@ -71,6 +71,7 @@ public:
|
|||||||
class MTGFlashBackRule: public MTGAlternativeCostRule
|
class MTGFlashBackRule: public MTGAlternativeCostRule
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
|
int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
|
||||||
int reactToClick(MTGCardInstance * card);
|
int reactToClick(MTGCardInstance * card);
|
||||||
int testDestroy();
|
int testDestroy();
|
||||||
@@ -98,9 +99,26 @@ public:
|
|||||||
virtual MTGRetraceRule * clone() const;
|
virtual MTGRetraceRule * clone() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MTGMorphCostRule: public MTGAbility
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
|
||||||
|
int reactToClick(MTGCardInstance * card);
|
||||||
|
int testDestroy();
|
||||||
|
virtual ostream& toString(ostream& out) const;
|
||||||
|
MTGMorphCostRule(int _id);
|
||||||
|
const char * getMenuText()
|
||||||
|
{
|
||||||
|
return "Play Morphed";
|
||||||
|
}
|
||||||
|
virtual MTGMorphCostRule * clone() const;
|
||||||
|
};
|
||||||
|
|
||||||
class MTGAttackRule: public MTGAbility, public Limitor
|
class MTGAttackRule: public MTGAbility, public Limitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual bool select(Target*);
|
virtual bool select(Target*);
|
||||||
virtual bool greyout(Target*);
|
virtual bool greyout(Target*);
|
||||||
int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
|
int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "MTGDefinitions.h"
|
#include "MTGDefinitions.h"
|
||||||
|
|
||||||
|
|
||||||
class ManaCostHybrid;
|
class ManaCostHybrid;
|
||||||
class ExtraCosts;
|
class ExtraCosts;
|
||||||
class ExtraCost;
|
class ExtraCost;
|
||||||
@@ -11,90 +12,89 @@ class MTGAbility;
|
|||||||
class MTGCardInstance;
|
class MTGCardInstance;
|
||||||
class Player;
|
class Player;
|
||||||
|
|
||||||
class ManaCost
|
class ManaCost{
|
||||||
{
|
protected:
|
||||||
protected:
|
int cost[Constants::MTG_NB_COLORS+1];
|
||||||
int cost[Constants::MTG_NB_COLORS + 1];
|
ManaCostHybrid * hybrids[10];
|
||||||
ManaCostHybrid * hybrids[10];
|
unsigned int nbhybrids;
|
||||||
unsigned int nbhybrids;
|
int extraCostsIsCopy;
|
||||||
int extraCostsIsCopy;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum
|
enum{
|
||||||
{
|
MANA_UNPAID = 0,
|
||||||
MANA_UNPAID = 0,
|
MANA_PAID = 1,
|
||||||
MANA_PAID = 1,
|
MANA_PAID_WITH_KICKER = 2,
|
||||||
MANA_PAID_WITH_KICKER = 2,
|
MANA_PAID_WITH_ALTERNATIVE = 3,
|
||||||
MANA_PAID_WITH_ALTERNATIVE = 3,
|
MANA_PAID_WITH_BUYBACK = 4,
|
||||||
MANA_PAID_WITH_BUYBACK = 4,
|
MANA_PAID_WITH_FLASHBACK = 5,
|
||||||
MANA_PAID_WITH_FLASHBACK = 5,
|
MANA_PAID_WITH_RETRACE = 6,
|
||||||
MANA_PAID_WITH_RETRACE = 6
|
MANA_PAID_WITH_MORPH = 7
|
||||||
|
|
||||||
};
|
};
|
||||||
ExtraCosts * extraCosts;
|
ExtraCosts * extraCosts;
|
||||||
ManaCost * kicker;
|
ManaCost * kicker;
|
||||||
ManaCost * alternative;
|
ManaCost * alternative;
|
||||||
ManaCost * BuyBack;
|
ManaCost * BuyBack;
|
||||||
ManaCost * FlashBack;
|
ManaCost * FlashBack;
|
||||||
ManaCost * Retrace;
|
ManaCost * Retrace;
|
||||||
static ManaCost * parseManaCost(string value, ManaCost * _manacost = NULL, MTGCardInstance * c = NULL);
|
ManaCost * morph;
|
||||||
virtual void init();
|
static ManaCost * parseManaCost(string value, ManaCost * _manacost = NULL, MTGCardInstance * c = NULL);
|
||||||
void x();
|
virtual void init();
|
||||||
int hasX();
|
void x();
|
||||||
ManaCost(int _cost[], int nb_elems = 1);
|
int hasX();
|
||||||
ManaCost();
|
ManaCost(int _cost[], int nb_elems = 1);
|
||||||
~ManaCost();
|
ManaCost();
|
||||||
ManaCost(ManaCost * _manaCost);
|
~ManaCost();
|
||||||
void copy(ManaCost * _manaCost);
|
ManaCost(ManaCost * _manaCost);
|
||||||
int isNull();
|
void copy (ManaCost * _manaCost);
|
||||||
int getConvertedCost();
|
int isNull();
|
||||||
string toString();
|
int getConvertedCost();
|
||||||
int getCost(int color);
|
string toString();
|
||||||
//Returns NULL if i is greater than nbhybrids
|
int getCost(int color);
|
||||||
ManaCostHybrid * getHybridCost(unsigned int i);
|
//Returns NULL if i is greater than nbhybrids
|
||||||
int hasColor(int color);
|
ManaCostHybrid * getHybridCost(unsigned int i);
|
||||||
int remove(int color, int value);
|
int hasColor(int color);
|
||||||
int add(int color, int value);
|
int remove (int color, int value);
|
||||||
|
int add(int color, int value);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Extra Costs (sacrifice,counters...)
|
// Extra Costs (sacrifice,counters...)
|
||||||
//
|
//
|
||||||
int addExtraCost(ExtraCost * _cost);
|
int addExtraCost(ExtraCost * _cost);
|
||||||
int setExtraCostsAction(MTGAbility * action, MTGCardInstance * card);
|
int setExtraCostsAction(MTGAbility * action, MTGCardInstance * card);
|
||||||
int isExtraPaymentSet();
|
int isExtraPaymentSet();
|
||||||
int canPayExtra();
|
int canPayExtra();
|
||||||
int doPayExtra();
|
int doPayExtra();
|
||||||
|
|
||||||
int addHybrid(int c1, int v1, int c2, int v2);
|
int addHybrid(int c1, int v1, int c2, int v2);
|
||||||
int tryToPayHybrids(ManaCostHybrid * _hybrids[], int _nbhybrids, int diff[]);
|
int tryToPayHybrids(ManaCostHybrid * _hybrids[], int _nbhybrids, int diff[]);
|
||||||
void randomDiffHybrids(ManaCost * _cost, int diff[]);
|
void randomDiffHybrids(ManaCost * _cost, int diff[]);
|
||||||
int add(ManaCost * _cost);
|
int add(ManaCost * _cost);
|
||||||
int pay(ManaCost * _cost);
|
int pay (ManaCost * _cost);
|
||||||
|
|
||||||
//return 1 if _cost can be paid with current data, 0 otherwise
|
//return 1 if _cost can be paid with current data, 0 otherwise
|
||||||
int canAfford(ManaCost * _cost);
|
int canAfford(ManaCost * _cost);
|
||||||
|
|
||||||
int isPositive();
|
int isPositive();
|
||||||
ManaCost * Diff(ManaCost * _cost);
|
ManaCost * Diff(ManaCost * _cost);
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
void Dump();
|
void Dump();
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& out, const ManaCost& m);
|
std::ostream& operator<<(std::ostream& out, const ManaCost& m);
|
||||||
|
|
||||||
class ManaPool: public ManaCost
|
class ManaPool:public ManaCost{
|
||||||
{
|
|
||||||
protected:
|
protected:
|
||||||
Player * player;
|
Player * player;
|
||||||
public:
|
public:
|
||||||
void init();
|
void init();
|
||||||
ManaPool(Player * player);
|
ManaPool(Player * player);
|
||||||
ManaPool(ManaCost * _manaCost, Player * player);
|
ManaPool(ManaCost * _manaCost, Player * player);
|
||||||
int remove(int color, int value);
|
int remove (int color, int value);
|
||||||
int add(int color, int value, MTGCardInstance * source = NULL);
|
int add(int color, int value, MTGCardInstance * source = NULL);
|
||||||
int add(ManaCost * _cost, MTGCardInstance * source = NULL);
|
int add(ManaCost * _cost, MTGCardInstance * source = NULL);
|
||||||
int pay(ManaCost * _cost);
|
int pay (ManaCost * _cost);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ public:
|
|||||||
bool onlyoneboth;
|
bool onlyoneboth;
|
||||||
bool bothrestrictedspell;
|
bool bothrestrictedspell;
|
||||||
bool bothrestrictedcreature;
|
bool bothrestrictedcreature;
|
||||||
|
bool isPoisoned;
|
||||||
MTGPlayerCards * game;
|
MTGPlayerCards * game;
|
||||||
string deckFile;
|
string deckFile;
|
||||||
string deckFileSmall;
|
string deckFileSmall;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Filter-like system for determining if a card meats certain criteria, for this and thisforeach autos
|
Filter-like system for determining if a card meats certain criteria, for this and thisforeach autos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _THISDESCRIPTOR_H_
|
#ifndef _THISDESCRIPTOR_H_
|
||||||
#define _THISDESCRIPTOR_H_
|
#define _THISDESCRIPTOR_H_
|
||||||
@@ -10,100 +10,117 @@
|
|||||||
#include "MTGCardInstance.h"
|
#include "MTGCardInstance.h"
|
||||||
#include "CardDescriptor.h"
|
#include "CardDescriptor.h"
|
||||||
|
|
||||||
class ThisDescriptor
|
class ThisDescriptor{
|
||||||
{
|
public:
|
||||||
public:
|
int comparisonMode;
|
||||||
int comparisonMode;
|
int comparisonCriterion;
|
||||||
int comparisonCriterion;
|
virtual int match(MTGCardInstance * card) = 0;
|
||||||
virtual int match(MTGCardInstance * card) = 0;
|
int matchValue(int value);
|
||||||
int matchValue(int value);
|
virtual ~ThisDescriptor();
|
||||||
virtual ~ThisDescriptor();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ThisDescriptorFactory
|
class ThisDescriptorFactory{
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
ThisDescriptor * createThisDescriptor(string s);
|
ThisDescriptor * createThisDescriptor(string s);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ThisCounter: public ThisDescriptor
|
class ThisCounter:public ThisDescriptor{
|
||||||
{
|
public:
|
||||||
public:
|
Counter * counter;
|
||||||
Counter * counter;
|
virtual int match(MTGCardInstance * card);
|
||||||
virtual int match(MTGCardInstance * card);
|
|
||||||
|
|
||||||
ThisCounter(Counter * _counter);
|
ThisCounter(Counter * _counter);
|
||||||
ThisCounter(int power, int toughness, int nb, const char * name);
|
ThisCounter(int power, int toughness, int nb, const char * name);
|
||||||
~ThisCounter();
|
~ThisCounter();
|
||||||
};
|
};
|
||||||
|
|
||||||
class ThisCounterAny: public ThisDescriptor
|
class ThisCounterAny:public ThisDescriptor{
|
||||||
{
|
public:
|
||||||
public:
|
virtual int match(MTGCardInstance *card);
|
||||||
virtual int match(MTGCardInstance *card);
|
|
||||||
|
|
||||||
ThisCounterAny(int nb);
|
ThisCounterAny(int nb);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ThisControllerlife: public ThisDescriptor
|
class ThisControllerlife:public ThisDescriptor{
|
||||||
{
|
public:
|
||||||
public:
|
|
||||||
virtual int match(MTGCardInstance * card);
|
virtual int match(MTGCardInstance * card);
|
||||||
|
|
||||||
ThisControllerlife(int life);
|
ThisControllerlife(int life);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ThisOpponentlife: public ThisDescriptor
|
class ThisOpponentlife:public ThisDescriptor{
|
||||||
{
|
public:
|
||||||
public:
|
|
||||||
virtual int match(MTGCardInstance * card);
|
virtual int match(MTGCardInstance * card);
|
||||||
|
|
||||||
ThisOpponentlife(int olife);
|
ThisOpponentlife(int olife);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ThisEquip: public ThisDescriptor
|
class ThisEquip:public ThisDescriptor{
|
||||||
{
|
public:
|
||||||
public:
|
|
||||||
virtual int match(MTGCardInstance * card);
|
virtual int match(MTGCardInstance * card);
|
||||||
|
|
||||||
ThisEquip(int equipment);
|
ThisEquip(int equipment);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ThisAttacked: public ThisDescriptor
|
class ThisAuras:public ThisDescriptor{
|
||||||
{
|
public:
|
||||||
public:
|
|
||||||
virtual int match(MTGCardInstance * card);
|
virtual int match(MTGCardInstance * card);
|
||||||
|
|
||||||
ThisAttacked(int attack);
|
ThisAuras(int auras);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ThisNotBlocked: public ThisDescriptor
|
class ThisOpponentDamageAmount:public ThisDescriptor{
|
||||||
{
|
public:
|
||||||
public:
|
|
||||||
virtual int match(MTGCardInstance * card);
|
virtual int match(MTGCardInstance * card);
|
||||||
|
|
||||||
ThisNotBlocked(int unblocked);
|
ThisOpponentDamageAmount(int damagecount);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ThisPower: public ThisDescriptor
|
class ThisUntapped:public ThisDescriptor{
|
||||||
{
|
public:
|
||||||
public:
|
virtual int match(MTGCardInstance * card);
|
||||||
|
|
||||||
|
ThisUntapped(int untapped);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ThisTapped:public ThisDescriptor{
|
||||||
|
public:
|
||||||
|
virtual int match(MTGCardInstance * card);
|
||||||
|
|
||||||
|
ThisTapped(int tapped);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ThisAttacked:public ThisDescriptor{
|
||||||
|
public:
|
||||||
|
virtual int match(MTGCardInstance * card);
|
||||||
|
|
||||||
|
ThisAttacked(int attack);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ThisNotBlocked:public ThisDescriptor{
|
||||||
|
public:
|
||||||
|
virtual int match(MTGCardInstance * card);
|
||||||
|
|
||||||
|
ThisNotBlocked(int unblocked);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ThisPower:public ThisDescriptor{
|
||||||
|
public:
|
||||||
virtual int match(MTGCardInstance * card);
|
virtual int match(MTGCardInstance * card);
|
||||||
|
|
||||||
ThisPower(int power);
|
ThisPower(int power);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ThisToughness: public ThisDescriptor
|
class ThisToughness:public ThisDescriptor{
|
||||||
{
|
public:
|
||||||
public:
|
|
||||||
virtual int match(MTGCardInstance * card);
|
virtual int match(MTGCardInstance * card);
|
||||||
|
|
||||||
ThisToughness(int toughness);
|
ThisToughness(int toughness);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ThisX: public ThisDescriptor
|
class ThisX:public ThisDescriptor{
|
||||||
{
|
public:
|
||||||
public:
|
|
||||||
virtual int match(MTGCardInstance * card);
|
virtual int match(MTGCardInstance * card);
|
||||||
ThisX(int x);
|
ThisX(int x);
|
||||||
};
|
};
|
||||||
|
|||||||
+126
-130
@@ -26,217 +26,213 @@ public:
|
|||||||
TARGET_FROM,
|
TARGET_FROM,
|
||||||
};
|
};
|
||||||
int type; //Deprecated, use dynamic casting instead
|
int type; //Deprecated, use dynamic casting instead
|
||||||
WEvent(int type = NOT_SPECIFIED);
|
WEvent(int type = NOT_SPECIFIED);
|
||||||
virtual ~WEvent() {};
|
virtual ~WEvent() {};
|
||||||
virtual std::ostream& toString(std::ostream& out) const;
|
virtual std::ostream& toString(std::ostream& out) const;
|
||||||
virtual int getValue()
|
virtual int getValue() {return 0;};
|
||||||
{
|
virtual Targetable * getTarget(int target) {return 0;};
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
virtual Targetable * getTarget(int target)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WEventZoneChange: public WEvent
|
struct WEventZoneChange : public WEvent {
|
||||||
{
|
MTGCardInstance * card;
|
||||||
MTGCardInstance * card;
|
MTGGameZone * from;
|
||||||
MTGGameZone * from;
|
MTGGameZone * to;
|
||||||
MTGGameZone * to;
|
WEventZoneChange(MTGCardInstance * card, MTGGameZone * from, MTGGameZone *to);
|
||||||
WEventZoneChange(MTGCardInstance * card, MTGGameZone * from, MTGGameZone *to);
|
virtual ~WEventZoneChange() {};
|
||||||
virtual ~WEventZoneChange() {};
|
virtual std::ostream& toString(std::ostream& out) const;
|
||||||
virtual std::ostream& toString(std::ostream& out) const;
|
virtual Targetable * getTarget(int target);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WEventDamage : public WEvent {
|
||||||
|
Damage * damage;
|
||||||
|
WEventDamage(Damage * damage);
|
||||||
|
virtual std::ostream& toString(std::ostream& out) const;
|
||||||
|
virtual int getValue();
|
||||||
|
virtual Targetable * getTarget(int target);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WEventLife : public WEvent {
|
||||||
|
Player * player;
|
||||||
|
int amount;
|
||||||
|
int Ltype;
|
||||||
|
WEventLife(Player * player,int amount,int Ltype = 0);
|
||||||
virtual Targetable * getTarget(int target);
|
virtual Targetable * getTarget(int target);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WEventDamage: public WEvent
|
struct WEventDamageStackResolved : public WEvent {
|
||||||
{
|
WEventDamageStackResolved();
|
||||||
Damage * damage;
|
|
||||||
WEventDamage(Damage * damage);
|
|
||||||
virtual std::ostream& toString(std::ostream& out) const;
|
|
||||||
virtual int getValue();
|
|
||||||
virtual Targetable * getTarget(int target);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WEventDamageStackResolved: public WEvent
|
struct WEventPhaseChange : public WEvent {
|
||||||
{
|
Phase * from;
|
||||||
WEventDamageStackResolved();
|
Phase * to;
|
||||||
|
WEventPhaseChange(Phase * from, Phase * to);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WEventPhaseChange: public WEvent
|
|
||||||
{
|
|
||||||
Phase * from;
|
|
||||||
Phase * to;
|
|
||||||
WEventPhaseChange(Phase * from, Phase * to);
|
|
||||||
};
|
|
||||||
|
|
||||||
//Abstract class of event when a card's status changes
|
//Abstract class of event when a card's status changes
|
||||||
struct WEventCardUpdate: public WEvent
|
struct WEventCardUpdate : public WEvent {
|
||||||
{
|
MTGCardInstance * card;
|
||||||
MTGCardInstance * card;
|
WEventCardUpdate(MTGCardInstance * card);
|
||||||
WEventCardUpdate(MTGCardInstance * card);
|
};
|
||||||
|
|
||||||
|
//creature damaged was killed, triggers effects targetter
|
||||||
|
struct WEventVampire : public WEventCardUpdate {
|
||||||
|
MTGCardInstance * card;
|
||||||
|
MTGCardInstance * source;
|
||||||
|
MTGCardInstance * victem;
|
||||||
|
WEventVampire(MTGCardInstance * card,MTGCardInstance * source,MTGCardInstance * victem);
|
||||||
|
virtual Targetable * getTarget(int target);
|
||||||
|
};
|
||||||
|
|
||||||
|
//creature became the target of a spell or ability
|
||||||
|
struct WEventTarget : public WEventCardUpdate {
|
||||||
|
MTGCardInstance * card;
|
||||||
|
MTGCardInstance * source;
|
||||||
|
WEventTarget(MTGCardInstance * card,MTGCardInstance * source);
|
||||||
|
virtual Targetable * getTarget(int target);
|
||||||
};
|
};
|
||||||
|
|
||||||
//Event when a card gains/looses types
|
//Event when a card gains/looses types
|
||||||
struct WEventCardChangeType: public WEventCardUpdate
|
struct WEventCardChangeType : public WEventCardUpdate {
|
||||||
{
|
int type;
|
||||||
int type;
|
bool before;
|
||||||
bool before;
|
bool after;
|
||||||
bool after;
|
WEventCardChangeType(MTGCardInstance * card, int type, bool before, bool after);
|
||||||
WEventCardChangeType(MTGCardInstance * card, int type, bool before, bool after);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//Event when a card is tapped/untapped
|
//Event when a card is tapped/untapped
|
||||||
struct WEventCardTap: public WEventCardUpdate
|
struct WEventCardTap : public WEventCardUpdate {
|
||||||
{
|
bool before;
|
||||||
bool before;
|
bool after;
|
||||||
bool after;
|
WEventCardTap(MTGCardInstance * card, bool before, bool after);
|
||||||
WEventCardTap(MTGCardInstance * card, bool before, bool after);
|
virtual Targetable * getTarget(int target);
|
||||||
virtual Targetable * getTarget(int target);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WEventCardTappedForMana: public WEventCardUpdate
|
struct WEventCardTappedForMana : public WEventCardUpdate {
|
||||||
{
|
bool before;
|
||||||
bool before;
|
bool after;
|
||||||
bool after;
|
WEventCardTappedForMana(MTGCardInstance * card, bool before, bool after);
|
||||||
WEventCardTappedForMana(MTGCardInstance * card, bool before, bool after);
|
virtual Targetable * getTarget(int target);
|
||||||
virtual Targetable * getTarget(int target);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//Event when a card's "attacker" status changes
|
//Event when a card's "attacker" status changes
|
||||||
//before:Player/Planeswalker that card was attacking previously
|
//before:Player/Planeswalker that card was attacking previously
|
||||||
//after: Player/Planeswalker that card is attacking now
|
//after: Player/Planeswalker that card is attacking now
|
||||||
struct WEventCreatureAttacker: public WEventCardUpdate
|
struct WEventCreatureAttacker : public WEventCardUpdate {
|
||||||
{
|
Targetable * before;
|
||||||
Targetable * before;
|
Targetable * after;
|
||||||
Targetable * after;
|
WEventCreatureAttacker(MTGCardInstance * card, Targetable * from, Targetable * to);
|
||||||
WEventCreatureAttacker(MTGCardInstance * card, Targetable * from, Targetable * to);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//event when card attacks.
|
//event when card attacks.
|
||||||
struct WEventCardAttacked: public WEventCardUpdate
|
struct WEventCardAttacked : public WEventCardUpdate {
|
||||||
{
|
WEventCardAttacked(MTGCardInstance * card);
|
||||||
WEventCardAttacked(MTGCardInstance * card);
|
virtual Targetable * getTarget(int target);
|
||||||
virtual Targetable * getTarget(int target);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//event when card attacks alone.
|
//event when card attacks alone.
|
||||||
struct WEventCardAttackedAlone: public WEventCardUpdate
|
struct WEventCardAttackedAlone : public WEventCardUpdate {
|
||||||
{
|
WEventCardAttackedAlone(MTGCardInstance * card);
|
||||||
WEventCardAttackedAlone(MTGCardInstance * card);
|
virtual Targetable * getTarget(int target);
|
||||||
virtual Targetable * getTarget(int target);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//event when card attacks but is not blocked.
|
//event when card attacks but is not blocked.
|
||||||
struct WEventCardAttackedNotBlocked: public WEventCardUpdate
|
struct WEventCardAttackedNotBlocked : public WEventCardUpdate {
|
||||||
{
|
WEventCardAttackedNotBlocked(MTGCardInstance * card);
|
||||||
WEventCardAttackedNotBlocked(MTGCardInstance * card);
|
virtual Targetable * getTarget(int target);
|
||||||
virtual Targetable * getTarget(int target);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//event when card attacks but is blocked.
|
//event when card attacks but is blocked.
|
||||||
struct WEventCardAttackedBlocked: public WEventCardUpdate
|
struct WEventCardAttackedBlocked : public WEventCardUpdate {
|
||||||
{
|
WEventCardAttackedBlocked(MTGCardInstance * card);
|
||||||
WEventCardAttackedBlocked(MTGCardInstance * card);
|
virtual Targetable * getTarget(int target);
|
||||||
virtual Targetable * getTarget(int target);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//event when card blocked.
|
//event when card blocked.
|
||||||
struct WEventCardBlocked: public WEventCardUpdate
|
struct WEventCardBlocked : public WEventCardUpdate {
|
||||||
{
|
WEventCardBlocked(MTGCardInstance * card);
|
||||||
WEventCardBlocked(MTGCardInstance * card);
|
virtual Targetable * getTarget(int target);
|
||||||
virtual Targetable * getTarget(int target);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//event when card is sacrificed.
|
//event when card is sacrificed.
|
||||||
struct WEventCardSacrifice: public WEventCardUpdate
|
struct WEventCardSacrifice : public WEventCardUpdate {
|
||||||
{
|
WEventCardSacrifice(MTGCardInstance * card);
|
||||||
WEventCardSacrifice(MTGCardInstance * card);
|
virtual Targetable * getTarget(int target);
|
||||||
virtual Targetable * getTarget(int target);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//event when card is discarded.
|
//event when card is discarded.
|
||||||
struct WEventCardDiscard: public WEventCardUpdate
|
struct WEventCardDiscard : public WEventCardUpdate {
|
||||||
{
|
WEventCardDiscard(MTGCardInstance * card);
|
||||||
WEventCardDiscard(MTGCardInstance * card);
|
virtual Targetable * getTarget(int target);
|
||||||
virtual Targetable * getTarget(int target);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//Event when a card's "defenser" status changes
|
//Event when a card's "defenser" status changes
|
||||||
//before : attacker that card was blocking previously
|
//before : attacker that card was blocking previously
|
||||||
//after: attacker that card is blocking now
|
//after: attacker that card is blocking now
|
||||||
struct WEventCreatureBlocker: public WEventCardUpdate
|
struct WEventCreatureBlocker : public WEventCardUpdate {
|
||||||
{
|
MTGCardInstance * before;
|
||||||
MTGCardInstance * before;
|
MTGCardInstance * after;
|
||||||
MTGCardInstance * after;
|
WEventCreatureBlocker(MTGCardInstance * card,MTGCardInstance * from,MTGCardInstance * to);
|
||||||
WEventCreatureBlocker(MTGCardInstance * card, MTGCardInstance * from, MTGCardInstance * to);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//Event sent when attackers have been chosen and they
|
//Event sent when attackers have been chosen and they
|
||||||
//cannot be changed any more.
|
//cannot be changed any more.
|
||||||
struct WEventAttackersChosen: public WEvent
|
struct WEventAttackersChosen : public WEvent {
|
||||||
{
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//Event sent when blockers have been chosen and they
|
//Event sent when blockers have been chosen and they
|
||||||
//cannot be changed any more.
|
//cannot be changed any more.
|
||||||
struct WEventBlockersChosen: public WEvent
|
struct WEventBlockersChosen : public WEvent {
|
||||||
{
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WEventcardDraw: public WEvent
|
struct WEventcardDraw : public WEvent {
|
||||||
{
|
WEventcardDraw(Player * player,int nb_cards);
|
||||||
WEventcardDraw(Player * player, int nb_cards);
|
Player * player;
|
||||||
Player * player;
|
int nb_cards;
|
||||||
int nb_cards;
|
virtual Targetable * getTarget(Player * player);
|
||||||
virtual Targetable * getTarget(Player * player);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//Event when a blocker is reordered
|
//Event when a blocker is reordered
|
||||||
//exchangeWith: exchange card's position with exchangeWith's position
|
//exchangeWith: exchange card's position with exchangeWith's position
|
||||||
//attacker:both card and exchangeWith *should* be in attacker's "blockers" list.
|
//attacker:both card and exchangeWith *should* be in attacker's "blockers" list.
|
||||||
struct WEventCreatureBlockerRank: public WEventCardUpdate
|
struct WEventCreatureBlockerRank : public WEventCardUpdate {
|
||||||
{
|
MTGCardInstance * exchangeWith;
|
||||||
MTGCardInstance * exchangeWith;
|
MTGCardInstance * attacker;
|
||||||
MTGCardInstance * attacker;
|
WEventCreatureBlockerRank(MTGCardInstance * card,MTGCardInstance * exchangeWith, MTGCardInstance * attacker);
|
||||||
WEventCreatureBlockerRank(MTGCardInstance * card, MTGCardInstance * exchangeWith, MTGCardInstance * attacker);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//Event when a combat phase step ends
|
//Event when a combat phase step ends
|
||||||
struct WEventCombatStepChange: public WEvent
|
struct WEventCombatStepChange : public WEvent
|
||||||
{
|
{
|
||||||
CombatStep step;
|
CombatStep step;
|
||||||
WEventCombatStepChange(CombatStep);
|
WEventCombatStepChange(CombatStep);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//Event when a mana is engaged
|
//Event when a mana is engaged
|
||||||
//color : color
|
//color : color
|
||||||
struct WEventEngageMana: public WEvent
|
struct WEventEngageMana : public WEvent {
|
||||||
{
|
int color;
|
||||||
int color;
|
MTGCardInstance* card;
|
||||||
MTGCardInstance* card;
|
ManaPool * destination;
|
||||||
ManaPool * destination;
|
WEventEngageMana(int color, MTGCardInstance* card, ManaPool * destination);
|
||||||
WEventEngageMana(int color, MTGCardInstance* card, ManaPool * destination);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//Event when a mana is consumed
|
//Event when a mana is consumed
|
||||||
//color : color
|
//color : color
|
||||||
struct WEventConsumeMana: public WEvent
|
struct WEventConsumeMana : public WEvent {
|
||||||
{
|
int color;
|
||||||
int color;
|
ManaPool * source;
|
||||||
ManaPool * source;
|
WEventConsumeMana(int color, ManaPool * source);
|
||||||
WEventConsumeMana(int color, ManaPool * source);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//Event when a manapool is emptied
|
//Event when a manapool is emptied
|
||||||
//color : color
|
//color : color
|
||||||
struct WEventEmptyManaPool: public WEvent
|
struct WEventEmptyManaPool : public WEvent {
|
||||||
{
|
ManaPool * source;
|
||||||
ManaPool * source;
|
WEventEmptyManaPool(ManaPool * source);
|
||||||
WEventEmptyManaPool(ManaPool * source);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream&, const WEvent&);
|
std::ostream& operator<<(std::ostream&, const WEvent&);
|
||||||
|
|||||||
+177
-105
@@ -150,7 +150,7 @@ ManaCost * AIPlayer::getPotentialMana(MTGCardInstance * target)
|
|||||||
MTGCardInstance * card = amp->source;
|
MTGCardInstance * card = amp->source;
|
||||||
if (card == target)
|
if (card == target)
|
||||||
used[card] = true; //http://code.google.com/p/wagic/issues/detail?id=76
|
used[card] = true; //http://code.google.com/p/wagic/issues/detail?id=76
|
||||||
if (!used[card] && amp->isReactingToClick(card) && amp->output->getConvertedCost() == 1)
|
if (!used[card] && amp->isReactingToClick(card) && amp->output->getConvertedCost() >= 1)
|
||||||
{
|
{
|
||||||
result->add(amp->output);
|
result->add(amp->output);
|
||||||
used[card] = true;
|
used[card] = true;
|
||||||
@@ -771,7 +771,7 @@ int AIPlayer::effectBadOrGood(MTGCardInstance * card, int mode, TargetChooser *
|
|||||||
return BAKA_EFFECT_DONTKNOW;
|
return BAKA_EFFECT_DONTKNOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AIPlayer::chooseTarget(TargetChooser * _tc, Player * forceTarget)
|
int AIPlayer::chooseTarget(TargetChooser * _tc, Player * forceTarget,MTGCardInstance * Choosencard)
|
||||||
{
|
{
|
||||||
vector<Targetable *> potentialTargets;
|
vector<Targetable *> potentialTargets;
|
||||||
TargetChooser * tc = _tc;
|
TargetChooser * tc = _tc;
|
||||||
@@ -780,11 +780,13 @@ int AIPlayer::chooseTarget(TargetChooser * _tc, Player * forceTarget)
|
|||||||
int checkOnly = 0;
|
int checkOnly = 0;
|
||||||
if (tc)
|
if (tc)
|
||||||
{
|
{
|
||||||
|
if(!Choosencard)
|
||||||
checkOnly = 1;
|
checkOnly = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tc = gameObs->getCurrentTargetChooser();
|
tc = gameObs->getCurrentTargetChooser();
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!tc)
|
if (!tc)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -845,6 +847,35 @@ int AIPlayer::chooseTarget(TargetChooser * _tc, Player * forceTarget)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//targetting the stack
|
||||||
|
zone = playerZones->stack;
|
||||||
|
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.push_back(card);
|
||||||
|
nbtargets++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (nbtargets)
|
if (nbtargets)
|
||||||
{
|
{
|
||||||
@@ -853,26 +884,28 @@ int AIPlayer::chooseTarget(TargetChooser * _tc, Player * forceTarget)
|
|||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case TARGET_CARD:
|
case TARGET_CARD:
|
||||||
{
|
{
|
||||||
MTGCardInstance * card = ((MTGCardInstance *) potentialTargets[i]);
|
MTGCardInstance * card = ((MTGCardInstance *) potentialTargets[i]);
|
||||||
clickstream.push(NEW AIAction(card));
|
clickstream.push(NEW AIAction(card));
|
||||||
return 1;
|
return 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TARGET_PLAYER:
|
case TARGET_PLAYER:
|
||||||
{
|
{
|
||||||
Player * player = ((Player *) potentialTargets[i]);
|
Player * player = ((Player *) potentialTargets[i]);
|
||||||
clickstream.push(NEW AIAction(player));
|
clickstream.push(NEW AIAction(player));
|
||||||
return 1;
|
return 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Couldn't find any valid target,
|
//Couldn't find any valid target,
|
||||||
//usually that's because we played a card that has bad side effects (ex: when X comes into play, return target land you own to your hand)
|
//usually that's because we played a card that has bad side effects (ex: when X comes into play, return target land you own to your hand)
|
||||||
//so we try again to choose a target in the other player's field...
|
//so we try again to choose a target in the other player's field...
|
||||||
if (checkOnly)
|
if (checkOnly)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
int cancel = gameObs->cancelCurrentAction();
|
int cancel = gameObs->cancelCurrentAction();
|
||||||
if (!cancel && !forceTarget)
|
if (!cancel && !forceTarget)
|
||||||
return chooseTarget(_tc, target->opponent());
|
return chooseTarget(_tc, target->opponent());
|
||||||
@@ -1180,6 +1213,7 @@ MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * pMana, const char * ty
|
|||||||
if (tc)
|
if (tc)
|
||||||
{
|
{
|
||||||
int hasTarget = (chooseTarget(tc));
|
int hasTarget = (chooseTarget(tc));
|
||||||
|
if(tc)
|
||||||
delete tc;
|
delete tc;
|
||||||
if (!hasTarget)
|
if (!hasTarget)
|
||||||
continue;
|
continue;
|
||||||
@@ -1241,7 +1275,6 @@ void AIPlayerBaka::initTimer()
|
|||||||
{
|
{
|
||||||
timer = 0.1f;
|
timer = 0.1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AIPlayerBaka::computeActions()
|
int AIPlayerBaka::computeActions()
|
||||||
{
|
{
|
||||||
GameObserver * g = GameObserver::GetInstance();
|
GameObserver * g = GameObserver::GetInstance();
|
||||||
@@ -1256,121 +1289,160 @@ int AIPlayerBaka::computeActions()
|
|||||||
if (chooseTarget())
|
if (chooseTarget())
|
||||||
return 1;
|
return 1;
|
||||||
int currentGamePhase = g->getCurrentGamePhase();
|
int currentGamePhase = g->getCurrentGamePhase();
|
||||||
if (g->isInterrupting == this)
|
static bool findingCard = false;
|
||||||
{ // interrupting
|
//this guard is put in place to prevent Ai from
|
||||||
selectAbility();
|
//ever running computeActions() function WHILE its already doing so.
|
||||||
return 1;
|
// Break if this happens in debug mode. If this happens, it's actually a bug
|
||||||
|
assert(!findingCard);
|
||||||
|
if (findingCard)
|
||||||
|
{//is already looking kick me out of this function!
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else if (p == this && g->mLayers->stackLayer()->count(0, NOT_RESOLVED) == 0)
|
if (p != this && (Player*)g->isInterrupting == this && g->mLayers->stackLayer()->count(0, NOT_RESOLVED) == 1)
|
||||||
|
{
|
||||||
|
findingCard = true;
|
||||||
|
CardDescriptor cd;
|
||||||
|
ManaCost * currentMana = getPotentialMana();
|
||||||
|
bool potential = false;
|
||||||
|
if (currentMana->getConvertedCost())
|
||||||
|
{
|
||||||
|
//if theres mana i can use there then potential is true.
|
||||||
|
potential = true;
|
||||||
|
}
|
||||||
|
//look for an instant of ability to interupt with
|
||||||
|
if((castrestrictedspell == false && nospellinstant == false)&&
|
||||||
|
(onlyonecast == false || castcount < 2) && (onlyoneinstant == false || castcount < 2))
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!nextCardToPlay)
|
||||||
|
{
|
||||||
|
nextCardToPlay = FindCardToPlay(currentMana, "instant");
|
||||||
|
}
|
||||||
|
if (!nextCardToPlay)
|
||||||
|
{
|
||||||
|
selectAbility();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentMana != NULL)
|
||||||
|
delete (currentMana);
|
||||||
|
if (nextCardToPlay)
|
||||||
|
{
|
||||||
|
if (potential)
|
||||||
|
{
|
||||||
|
tapLandsForMana(nextCardToPlay->getManaCost());
|
||||||
|
}
|
||||||
|
AIAction * a = NEW AIAction(nextCardToPlay);
|
||||||
|
clickstream.push(a);
|
||||||
|
findingCard = false;
|
||||||
|
nextCardToPlay = NULL;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
nextCardToPlay = NULL;
|
||||||
|
findingCard = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if(p == this && g->mLayers->stackLayer()->count(0, NOT_RESOLVED) == 0)
|
||||||
{ //standard actions
|
{ //standard actions
|
||||||
CardDescriptor cd;
|
CardDescriptor cd;
|
||||||
|
|
||||||
switch (currentGamePhase)
|
switch (currentGamePhase)
|
||||||
{
|
{
|
||||||
case Constants::MTG_PHASE_FIRSTMAIN:
|
case Constants::MTG_PHASE_FIRSTMAIN:
|
||||||
case Constants::MTG_PHASE_SECONDMAIN:
|
case Constants::MTG_PHASE_SECONDMAIN:
|
||||||
{
|
|
||||||
|
|
||||||
bool potential = false;
|
|
||||||
ManaCost * currentMana = getPotentialMana();
|
|
||||||
if (currentMana->getConvertedCost())
|
|
||||||
{
|
{
|
||||||
//if theres mana i can use there then potential is true.
|
ManaCost * currentMana = getPotentialMana();
|
||||||
potential = true;
|
bool potential = false;
|
||||||
}
|
if (currentMana->getConvertedCost())
|
||||||
nextCardToPlay = FindCardToPlay(currentMana, "land");
|
|
||||||
selectAbility();
|
|
||||||
//look for the most expensive creature we can afford
|
|
||||||
if (castrestrictedspell == false && nospellinstant == false)
|
|
||||||
{
|
|
||||||
if (onlyonecast == false || castcount < 2)
|
|
||||||
{
|
{
|
||||||
if (onlyoneinstant == false || castcount < 2)
|
//if theres mana i can use there then potential is true.
|
||||||
|
potential = true;
|
||||||
|
}
|
||||||
|
nextCardToPlay = FindCardToPlay(currentMana, "land");
|
||||||
|
selectAbility();
|
||||||
|
//look for the most expensive creature we can afford
|
||||||
|
if((castrestrictedspell == false && nospellinstant == false)&&
|
||||||
|
(onlyonecast == false || castcount < 2)&&(onlyoneinstant == false || castcount < 2))
|
||||||
|
{
|
||||||
|
if (castrestrictedcreature == false && nocreatureinstant == false)
|
||||||
{
|
{
|
||||||
if (castrestrictedcreature == false && nocreatureinstant == false)
|
|
||||||
{
|
|
||||||
if (!nextCardToPlay)
|
|
||||||
{
|
|
||||||
nextCardToPlay = FindCardToPlay(currentMana, "creature");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Let's Try an enchantment maybe ?
|
|
||||||
if (!nextCardToPlay)
|
if (!nextCardToPlay)
|
||||||
{
|
{
|
||||||
nextCardToPlay = FindCardToPlay(currentMana, "enchantment");
|
nextCardToPlay = FindCardToPlay(currentMana, "creature");
|
||||||
}
|
|
||||||
if (!nextCardToPlay)
|
|
||||||
{
|
|
||||||
nextCardToPlay = FindCardToPlay(currentMana, "artifact");
|
|
||||||
}
|
|
||||||
if (!nextCardToPlay)
|
|
||||||
{
|
|
||||||
nextCardToPlay = FindCardToPlay(currentMana, "sorcery");
|
|
||||||
}
|
|
||||||
if (!nextCardToPlay)
|
|
||||||
{
|
|
||||||
nextCardToPlay = FindCardToPlay(currentMana, "instant");
|
|
||||||
}
|
|
||||||
if (!nextCardToPlay)
|
|
||||||
{
|
|
||||||
selectAbility();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
//Let's Try an enchantment maybe ?
|
||||||
|
if (!nextCardToPlay)
|
||||||
}
|
|
||||||
if (currentMana != NULL)
|
|
||||||
delete (currentMana);
|
|
||||||
if (nextCardToPlay)
|
|
||||||
{
|
|
||||||
if (potential)
|
|
||||||
{
|
|
||||||
/////////////////////////
|
|
||||||
//had to force this on Ai other wise it would pay nothing but 1 color for a sunburst card.
|
|
||||||
//this does not teach it to use manaproducer more effectively, it simply allow it to use the manaproducers it does understand better on sunburst by force.
|
|
||||||
if (nextCardToPlay->has(Constants::SUNBURST))
|
|
||||||
{
|
{
|
||||||
ManaCost * SunCheck = manaPool;
|
nextCardToPlay = FindCardToPlay(currentMana, "enchantment");
|
||||||
SunCheck = getPotentialMana();
|
}
|
||||||
for (int i = Constants::MTG_NB_COLORS - 1; i > 0; i--)
|
if (!nextCardToPlay)
|
||||||
|
{
|
||||||
|
nextCardToPlay = FindCardToPlay(currentMana, "artifact");
|
||||||
|
}
|
||||||
|
if (!nextCardToPlay)
|
||||||
|
{
|
||||||
|
nextCardToPlay = FindCardToPlay(currentMana, "sorcery");
|
||||||
|
}
|
||||||
|
if (!nextCardToPlay)
|
||||||
|
{
|
||||||
|
nextCardToPlay = FindCardToPlay(currentMana, "instant");
|
||||||
|
}
|
||||||
|
if (!nextCardToPlay)
|
||||||
|
{
|
||||||
|
selectAbility();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentMana != NULL)
|
||||||
|
delete (currentMana);
|
||||||
|
if (nextCardToPlay)
|
||||||
|
{
|
||||||
|
if (potential)
|
||||||
|
{
|
||||||
|
/////////////////////////
|
||||||
|
//had to force this on Ai other wise it would pay nothing but 1 color for a sunburst card.
|
||||||
|
//this does not teach it to use manaproducer more effectively, it simply allow it to use the manaproducers it does understand better on sunburst by force.
|
||||||
|
if (nextCardToPlay->has(Constants::SUNBURST))
|
||||||
{
|
{
|
||||||
//sunburst for Ai
|
ManaCost * SunCheck = manaPool;
|
||||||
if (SunCheck->hasColor(i))
|
SunCheck = getPotentialMana();
|
||||||
|
for (int i = Constants::MTG_NB_COLORS - 1; i > 0; i--)
|
||||||
{
|
{
|
||||||
if (nextCardToPlay->getManaCost()->hasColor(i) > 0)
|
//sunburst for Ai
|
||||||
{//do nothing if the card already has this color.
|
if (SunCheck->hasColor(i))
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if (nextCardToPlay->sunburst < nextCardToPlay->getManaCost()->getConvertedCost())
|
if (nextCardToPlay->getManaCost()->hasColor(i) > 0)
|
||||||
|
{//do nothing if the card already has this color.
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
nextCardToPlay->getManaCost()->add(i, 1);
|
if (nextCardToPlay->sunburst < nextCardToPlay->getManaCost()->getConvertedCost())
|
||||||
nextCardToPlay->getManaCost()->remove(0, 1);
|
{
|
||||||
nextCardToPlay->sunburst += 1;
|
nextCardToPlay->getManaCost()->add(i, 1);
|
||||||
|
nextCardToPlay->getManaCost()->remove(0, 1);
|
||||||
|
nextCardToPlay->sunburst += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
delete (SunCheck);
|
||||||
}
|
}
|
||||||
delete (SunCheck);
|
/////////////////////////
|
||||||
|
tapLandsForMana(nextCardToPlay->getManaCost());
|
||||||
}
|
}
|
||||||
/////////////////////////
|
AIAction * a = NEW AIAction(nextCardToPlay);
|
||||||
tapLandsForMana(nextCardToPlay->getManaCost());
|
clickstream.push(a);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
AIAction * a = NEW AIAction(nextCardToPlay);
|
else
|
||||||
clickstream.push(a);
|
{
|
||||||
return 1;
|
selectAbility();
|
||||||
|
}
|
||||||
|
if (p->getManaPool()->getConvertedCost() > 0 && Checked == false)//not the best thing ever, but allows the Ai a chance to double check if its mana pool has something before moving on, atleast one time.
|
||||||
|
{
|
||||||
|
Checked = true;
|
||||||
|
computeActions();
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
selectAbility();
|
|
||||||
}
|
|
||||||
if (p->getManaPool()->getConvertedCost() > 0 && Checked == false)//not the best thing ever, but allows the Ai a chance to double check if its mana pool has something before moving on, atleast one time.
|
|
||||||
{
|
|
||||||
Checked = true;
|
|
||||||
computeActions();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Constants::MTG_PHASE_COMBATATTACKERS:
|
case Constants::MTG_PHASE_COMBATATTACKERS:
|
||||||
chooseAttackers();
|
chooseAttackers();
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -214,7 +214,8 @@ Interruptible(id), tc(tc), cost(_cost), payResult(payResult)
|
|||||||
int Spell::computeX(MTGCardInstance * card)
|
int Spell::computeX(MTGCardInstance * card)
|
||||||
{
|
{
|
||||||
ManaCost * c = cost->Diff(card->getManaCost());
|
ManaCost * c = cost->Diff(card->getManaCost());
|
||||||
int x = c->getCost(Constants::MTG_NB_COLORS);
|
int x = 0;
|
||||||
|
x = c->getCost(Constants::MTG_NB_COLORS);
|
||||||
delete c;
|
delete c;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
@@ -222,7 +223,8 @@ int Spell::computeX(MTGCardInstance * card)
|
|||||||
int Spell::computeXX(MTGCardInstance * card)
|
int Spell::computeXX(MTGCardInstance * card)
|
||||||
{
|
{
|
||||||
ManaCost * c = cost->Diff(card->getManaCost());
|
ManaCost * c = cost->Diff(card->getManaCost());
|
||||||
int xx = c->getCost(Constants::MTG_NB_COLORS) / 2;
|
int xx = 0;
|
||||||
|
xx = c->getCost(Constants::MTG_NB_COLORS) / 2;
|
||||||
delete c;
|
delete c;
|
||||||
return xx;
|
return xx;
|
||||||
}
|
}
|
||||||
@@ -451,7 +453,39 @@ ostream& DrawAction::toString(ostream& out) const
|
|||||||
out << "DrawAction ::: nbcards : " << nbcards << " ; player : " << player;
|
out << "DrawAction ::: nbcards : " << nbcards << " ; player : " << player;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
//////
|
||||||
|
LifeAction::LifeAction(int id, Damageable * _target, int amount) :
|
||||||
|
Interruptible(id), amount(amount),target(_target)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int LifeAction::resolve()
|
||||||
|
{
|
||||||
|
target->life += amount;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LifeAction::Render()
|
||||||
|
{
|
||||||
|
WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT);
|
||||||
|
mFont->SetBase(0);
|
||||||
|
mFont->SetScale(DEFAULT_MAIN_FONT_SCALE);
|
||||||
|
char buffer[200];
|
||||||
|
if(amount >= 0)
|
||||||
|
sprintf(buffer, _("Player gains %i life").c_str(), amount);
|
||||||
|
else if(amount >= 0)
|
||||||
|
sprintf(buffer, _("Player loses %i life").c_str(), amount);
|
||||||
|
else
|
||||||
|
sprintf(buffer, _("Nothing happened").c_str(), amount);
|
||||||
|
mFont->DrawString(buffer, x + 20, y, JGETEXT_LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
ostream& LifeAction::toString(ostream& out) const
|
||||||
|
{
|
||||||
|
out << "LifeAction ::: amount : " << amount << " ; target : " << target;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
/* The Action Stack itself */
|
||||||
int ActionStack::addPutInGraveyard(MTGCardInstance * card)
|
int ActionStack::addPutInGraveyard(MTGCardInstance * card)
|
||||||
{
|
{
|
||||||
PutInGraveyard * death = NEW PutInGraveyard(mCount, card);
|
PutInGraveyard * death = NEW PutInGraveyard(mCount, card);
|
||||||
@@ -482,10 +516,20 @@ int ActionStack::addDraw(Player * player, int nb_cards)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ActionStack::addLife(Damageable * _target, int amount)
|
||||||
|
{
|
||||||
|
LifeAction * life = NEW LifeAction(mCount, _target, amount);
|
||||||
|
addAction(life);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int ActionStack::addDamage(MTGCardInstance * _source, Damageable * _target, int _damage)
|
int ActionStack::addDamage(MTGCardInstance * _source, Damageable * _target, int _damage)
|
||||||
{
|
{
|
||||||
Damage * damage = NEW Damage(_source, _target, _damage);
|
Damage * damage = NEW Damage(_source, _target, _damage);
|
||||||
addAction(damage);
|
addAction(damage);
|
||||||
|
_source->thatmuch = _damage;
|
||||||
|
_target->thatmuch = _damage;
|
||||||
|
_target->lifeLostThisTurn += _damage;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1278
-112
File diff suppressed because it is too large
Load Diff
@@ -42,6 +42,32 @@ void CardDescriptor::unsecuresetfresh(int k)
|
|||||||
fresh = k;
|
fresh = k;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CardDescriptor::setisMultiColored(int w)
|
||||||
|
{
|
||||||
|
isMultiColored = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardDescriptor::setisBlackAndWhite(int w)
|
||||||
|
{
|
||||||
|
isBlackAndWhite = w;
|
||||||
|
}
|
||||||
|
void CardDescriptor::setisRedAndBlue(int w)
|
||||||
|
{
|
||||||
|
isRedAndBlue = w;
|
||||||
|
}
|
||||||
|
void CardDescriptor::setisBlackAndGreen(int w)
|
||||||
|
{
|
||||||
|
isBlackAndGreen = w;
|
||||||
|
}
|
||||||
|
void CardDescriptor::setisBlueAndGreen(int w)
|
||||||
|
{
|
||||||
|
isBlueAndGreen = w;
|
||||||
|
}
|
||||||
|
void CardDescriptor::setisRedAndWhite(int w)
|
||||||
|
{
|
||||||
|
isRedAndWhite = w;
|
||||||
|
}
|
||||||
|
|
||||||
void CardDescriptor::setNegativeSubtype(string value)
|
void CardDescriptor::setNegativeSubtype(string value)
|
||||||
{
|
{
|
||||||
int id = Subtypes::subtypesList->find(value);
|
int id = Subtypes::subtypesList->find(value);
|
||||||
@@ -203,10 +229,42 @@ MTGCardInstance * CardDescriptor::match(MTGCardInstance * card)
|
|||||||
match = NULL;
|
match = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((isToken == -1 && card->isToken) || (isToken == 1 && !card->isToken))
|
if ((isMultiColored == -1 && card->isMultiColored) || (isMultiColored == 1 && !card->isMultiColored))
|
||||||
{
|
{
|
||||||
match = NULL;
|
match = NULL;
|
||||||
}
|
}
|
||||||
|
if ((isBlackAndWhite == -1 && card->isBlackAndWhite) || (isBlackAndWhite == 1 && !card->isBlackAndWhite))
|
||||||
|
{
|
||||||
|
match = NULL;
|
||||||
|
}
|
||||||
|
if ((isRedAndBlue == -1 && card->isRedAndBlue) || (isRedAndBlue == 1 && !card->isRedAndBlue))
|
||||||
|
{
|
||||||
|
match = NULL;
|
||||||
|
}
|
||||||
|
if ((isBlackAndGreen == -1 && card->isBlackAndGreen) || (isBlackAndGreen == 1 && !card->isBlackAndGreen))
|
||||||
|
{
|
||||||
|
match = NULL;
|
||||||
|
}
|
||||||
|
if ((isBlueAndGreen == -1 && card->isBlueAndGreen) || (isBlueAndGreen == 1 && !card->isBlueAndGreen))
|
||||||
|
{
|
||||||
|
match = NULL;
|
||||||
|
}
|
||||||
|
if ((isRedAndWhite == -1 && card->isRedAndWhite) || (isRedAndWhite == 1 && !card->isRedAndWhite))
|
||||||
|
{
|
||||||
|
match = NULL;
|
||||||
|
}
|
||||||
|
if ((isLeveler == -1 && card->isLeveler) || (isLeveler == 1 && !card->isLeveler))
|
||||||
|
{
|
||||||
|
match = NULL;
|
||||||
|
}
|
||||||
|
if ((CDenchanted == -1 && card->enchanted) || (CDenchanted == 1 && !card->enchanted))
|
||||||
|
{
|
||||||
|
match = NULL;
|
||||||
|
}
|
||||||
|
if ((isToken == -1 && card->isToken) || (isToken == 1 && !card->isToken))
|
||||||
|
{
|
||||||
|
match = NULL;
|
||||||
|
}
|
||||||
if (attacker == 1)
|
if (attacker == 1)
|
||||||
{
|
{
|
||||||
if (defenser == &AnyCard)
|
if (defenser == &AnyCard)
|
||||||
|
|||||||
@@ -141,6 +141,7 @@ void CardGui::Render()
|
|||||||
|
|
||||||
bool alternate = true;
|
bool alternate = true;
|
||||||
JQuad * quad = WResourceManager::Instance()->RetrieveCard(card, CACHE_THUMB);
|
JQuad * quad = WResourceManager::Instance()->RetrieveCard(card, CACHE_THUMB);
|
||||||
|
|
||||||
#if defined (WIN32) || defined (LINUX)
|
#if defined (WIN32) || defined (LINUX)
|
||||||
//On pcs we render the big image if the thumbnail is not available
|
//On pcs we render the big image if the thumbnail is not available
|
||||||
if (!quad) quad = WResourceManager::Instance()->RetrieveCard(card);
|
if (!quad) quad = WResourceManager::Instance()->RetrieveCard(card);
|
||||||
@@ -160,7 +161,13 @@ void CardGui::Render()
|
|||||||
shadow->SetColor(ARGB(static_cast<unsigned char>(actA)/2,255,255,255));
|
shadow->SetColor(ARGB(static_cast<unsigned char>(actA)/2,255,255,255));
|
||||||
renderer->RenderQuad(shadow, actX + (actZ - 1) * 15, actY + (actZ - 1) * 15, actT, 28 * actZ / 16, 40 * actZ / 16);
|
renderer->RenderQuad(shadow, actX + (actZ - 1) * 15, actY + (actZ - 1) * 15, actT, 28 * actZ / 16, 40 * actZ / 16);
|
||||||
}
|
}
|
||||||
|
JQuad* extracostshadow = NULL;
|
||||||
|
if(card->isExtraCostTarget == true)
|
||||||
|
{
|
||||||
|
extracostshadow = WResourceManager::Instance()->GetQuad("extracostshadow");
|
||||||
|
extracostshadow->SetColor(ARGB(static_cast<unsigned char>(actA)/2,100,0,0));
|
||||||
|
renderer->RenderQuad(extracostshadow, actX + (actZ - 1) * 15, actY + (actZ - 1) * 15, actT, 28 * actZ / 16, 40 * actZ / 16);
|
||||||
|
}
|
||||||
if (quad)
|
if (quad)
|
||||||
{
|
{
|
||||||
quad->SetColor(ARGB(static_cast<unsigned char>(actA),255,255,255));
|
quad->SetColor(ARGB(static_cast<unsigned char>(actA),255,255,255));
|
||||||
@@ -194,6 +201,14 @@ void CardGui::Render()
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
JQuad * mor = NULL;
|
||||||
|
if(card->isMorphed && !alternate)
|
||||||
|
{
|
||||||
|
mor = WResourceManager::Instance()->GetQuad("morph");
|
||||||
|
mor->SetColor(ARGB(255,255,255,255));
|
||||||
|
renderer->RenderQuad(mor, actX, actY, actT,scale, scale);
|
||||||
|
}
|
||||||
|
|
||||||
//draws the numbers power/toughness
|
//draws the numbers power/toughness
|
||||||
if (card->isCreature())
|
if (card->isCreature())
|
||||||
{
|
{
|
||||||
@@ -236,7 +251,6 @@ void CardGui::Render()
|
|||||||
shadow->SetColor(ARGB(200,255,255,255));
|
shadow->SetColor(ARGB(200,255,255,255));
|
||||||
renderer->RenderQuad(shadow, actX, actY, actT, (28 * actZ + 1) / 16, 40 * actZ / 16);
|
renderer->RenderQuad(shadow, actX, actY, actT, (28 * actZ + 1) / 16, 40 * actZ / 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayGuiObject::Render();
|
PlayGuiObject::Render();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -552,6 +566,7 @@ void CardGui::TinyCropRender(MTGCard * card, const Pos& pos, JQuad * quad)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (q && q->mTex)
|
if (q && q->mTex)
|
||||||
{
|
{
|
||||||
q->SetHotSpot(static_cast<float> (q->mTex->mWidth / 2), static_cast<float> (q->mTex->mHeight / 2));
|
q->SetHotSpot(static_cast<float> (q->mTex->mWidth / 2), static_cast<float> (q->mTex->mHeight / 2));
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ CardPrimitive::CardPrimitive(CardPrimitive * source)
|
|||||||
|
|
||||||
power = source->power;
|
power = source->power;
|
||||||
toughness = source->toughness;
|
toughness = source->toughness;
|
||||||
|
restriction = source->restriction;
|
||||||
|
otherrestriction = source->otherrestriction;
|
||||||
|
|
||||||
magicText = source->magicText;
|
magicText = source->magicText;
|
||||||
for (map<string, string>::const_iterator it = source->magicTexts.begin(); it != source->magicTexts.end(); ++it)
|
for (map<string, string>::const_iterator it = source->magicTexts.begin(); it != source->magicTexts.end(); ++it)
|
||||||
@@ -50,6 +52,7 @@ int CardPrimitive::init()
|
|||||||
magicTexts.clear();
|
magicTexts.clear();
|
||||||
spellTargetType = "";
|
spellTargetType = "";
|
||||||
alias = 0;
|
alias = 0;
|
||||||
|
bool hasRestriction = false;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,6 +86,24 @@ bool CardPrimitive::isSpell()
|
|||||||
return (!isCreature() && !isLand());
|
return (!isCreature() && !isLand());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CardPrimitive::setRestrictions(int _restriction)
|
||||||
|
{
|
||||||
|
restriction = _restriction;
|
||||||
|
}
|
||||||
|
int CardPrimitive::getRestrictions()
|
||||||
|
{
|
||||||
|
return restriction;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CardPrimitive::setOtherRestrictions(string _restriction)
|
||||||
|
{
|
||||||
|
otherrestriction = _restriction;
|
||||||
|
}
|
||||||
|
void CardPrimitive::getOtherRestrictions()
|
||||||
|
{
|
||||||
|
otherrestriction;
|
||||||
|
}
|
||||||
|
|
||||||
void CardPrimitive::setColor(string _color, int removeAllOthers)
|
void CardPrimitive::setColor(string _color, int removeAllOthers)
|
||||||
{
|
{
|
||||||
if (_color.compare("blue") == 0)
|
if (_color.compare("blue") == 0)
|
||||||
|
|||||||
@@ -94,7 +94,9 @@ int Damage::resolve()
|
|||||||
}
|
}
|
||||||
if ((_target)->has(Constants::ABSORB))
|
if ((_target)->has(Constants::ABSORB))
|
||||||
{
|
{
|
||||||
damage -= 1;
|
damage -= (_target)->basicAbilities[Constants::ABSORB];
|
||||||
|
if(damage < 0)
|
||||||
|
damage = 0;
|
||||||
}
|
}
|
||||||
if ((_target)->has(Constants::WILTING))
|
if ((_target)->has(Constants::WILTING))
|
||||||
{
|
{
|
||||||
@@ -132,6 +134,8 @@ int Damage::resolve()
|
|||||||
{
|
{
|
||||||
_target->counters->addCounter(-1, -1);
|
_target->counters->addCounter(-1, -1);
|
||||||
}
|
}
|
||||||
|
if(_target->toughness <= 0 && _target->has(Constants::INDESTRUCTIBLE))
|
||||||
|
_target->controller()->game->putInGraveyard(_target);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (target->type_as_damageable == DAMAGEABLE_PLAYER && source->has(Constants::INFECT))
|
else if (target->type_as_damageable == DAMAGEABLE_PLAYER && source->has(Constants::INFECT))
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ void DuelLayers::init()
|
|||||||
action->Add(NEW MTGLifelinkRule(-1));
|
action->Add(NEW MTGLifelinkRule(-1));
|
||||||
action->Add(NEW MTGDeathtouchRule(-1));
|
action->Add(NEW MTGDeathtouchRule(-1));
|
||||||
action->Add(NEW OtherAbilitiesEventReceiver(-1));
|
action->Add(NEW OtherAbilitiesEventReceiver(-1));
|
||||||
|
action->Add(NEW MTGMorphCostRule(-1));
|
||||||
//Other display elements
|
//Other display elements
|
||||||
action->Add(NEW HUDDisplay(-1));
|
action->Add(NEW HUDDisplay(-1));
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,13 @@ int LifeCost::doPay()
|
|||||||
MTGCardInstance * _target = (MTGCardInstance *) target;
|
MTGCardInstance * _target = (MTGCardInstance *) target;
|
||||||
if (target)
|
if (target)
|
||||||
{
|
{
|
||||||
|
_target->controller()->thatmuch = 1;
|
||||||
|
WEvent * lifed = NULL;
|
||||||
|
lifed = NEW WEventLife(_target->controller(),-1,1);
|
||||||
|
GameObserver * game = GameObserver::GetInstance();
|
||||||
|
game->receiveEvent(lifed);
|
||||||
_target->controller()->life -= 1;
|
_target->controller()->life -= 1;
|
||||||
|
_target->controller()->lifeLostThisTurn += 1;
|
||||||
target = NULL;
|
target = NULL;
|
||||||
if (tc)
|
if (tc)
|
||||||
tc->initTargets();
|
tc->initTargets();
|
||||||
@@ -263,6 +269,20 @@ TapTargetCost::TapTargetCost(TargetChooser *_tc) :
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TapTargetCost::isPaymentSet()
|
||||||
|
{
|
||||||
|
if (target && target->isTapped())
|
||||||
|
{
|
||||||
|
tc->removeTarget(target);
|
||||||
|
target->isExtraCostTarget = false;
|
||||||
|
target = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (target)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int TapTargetCost::doPay()
|
int TapTargetCost::doPay()
|
||||||
{
|
{
|
||||||
MTGCardInstance * _target = (MTGCardInstance *) target;
|
MTGCardInstance * _target = (MTGCardInstance *) target;
|
||||||
@@ -563,8 +583,19 @@ int ExtraCosts::tryToSetPayment(MTGCardInstance * card)
|
|||||||
{
|
{
|
||||||
for (size_t i = 0; i < costs.size(); i++)
|
for (size_t i = 0; i < costs.size(); i++)
|
||||||
{
|
{
|
||||||
if (int result = costs[i]->setPayment(card))
|
if(!costs[i]->isPaymentSet())
|
||||||
return result;
|
{
|
||||||
|
for(size_t k = 0; k < costs.size(); k++)
|
||||||
|
{
|
||||||
|
if(card == costs[k]->target)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (int result = costs[i]->setPayment(card))
|
||||||
|
{
|
||||||
|
card->isExtraCostTarget = true;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -584,7 +615,10 @@ int ExtraCosts::canPay()
|
|||||||
for (size_t i = 0; i < costs.size(); i++)
|
for (size_t i = 0; i < costs.size(); i++)
|
||||||
{
|
{
|
||||||
if (!costs[i]->canPay())
|
if (!costs[i]->canPay())
|
||||||
|
{
|
||||||
|
costs[i]->target->isExtraCostTarget = false;
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -594,6 +628,8 @@ int ExtraCosts::doPay()
|
|||||||
int result = 0;
|
int result = 0;
|
||||||
for (size_t i = 0; i < costs.size(); i++)
|
for (size_t i = 0; i < costs.size(); i++)
|
||||||
{
|
{
|
||||||
|
if(costs[i]->target)
|
||||||
|
costs[i]->target->isExtraCostTarget = false;
|
||||||
result += costs[i]->doPay();
|
result += costs[i]->doPay();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -191,6 +191,8 @@ void GameApp::Create()
|
|||||||
WResourceManager::Instance()->RetrieveTexture("BattleIcon.png", RETRIEVE_MANAGE);
|
WResourceManager::Instance()->RetrieveTexture("BattleIcon.png", RETRIEVE_MANAGE);
|
||||||
WResourceManager::Instance()->RetrieveTexture("DefenderIcon.png", RETRIEVE_MANAGE);
|
WResourceManager::Instance()->RetrieveTexture("DefenderIcon.png", RETRIEVE_MANAGE);
|
||||||
WResourceManager::Instance()->RetrieveTexture("shadow.png", RETRIEVE_MANAGE);
|
WResourceManager::Instance()->RetrieveTexture("shadow.png", RETRIEVE_MANAGE);
|
||||||
|
WResourceManager::Instance()->RetrieveTexture("extracostshadow.png", RETRIEVE_MANAGE);
|
||||||
|
WResourceManager::Instance()->RetrieveTexture("morph.jpg", RETRIEVE_MANAGE);
|
||||||
|
|
||||||
jq = WResourceManager::Instance()->RetrieveQuad("BattleIcon.png", 0, 0, 25, 25, "BattleIcon", RETRIEVE_MANAGE);
|
jq = WResourceManager::Instance()->RetrieveQuad("BattleIcon.png", 0, 0, 25, 25, "BattleIcon", RETRIEVE_MANAGE);
|
||||||
if (jq)
|
if (jq)
|
||||||
@@ -201,6 +203,12 @@ void GameApp::Create()
|
|||||||
jq = WResourceManager::Instance()->RetrieveQuad("shadow.png", 0, 0, 16, 16, "shadow", RETRIEVE_MANAGE);
|
jq = WResourceManager::Instance()->RetrieveQuad("shadow.png", 0, 0, 16, 16, "shadow", RETRIEVE_MANAGE);
|
||||||
if (jq)
|
if (jq)
|
||||||
jq->SetHotSpot(8, 8);
|
jq->SetHotSpot(8, 8);
|
||||||
|
jq = WResourceManager::Instance()->RetrieveQuad("extracostshadow.png", 0, 0, 16, 16, "extracostshadow", RETRIEVE_MANAGE);
|
||||||
|
if (jq)
|
||||||
|
jq->SetHotSpot(8, 8);
|
||||||
|
jq = WResourceManager::Instance()->RetrieveQuad("morph.jpg", 0, 0, MTG_MINIIMAGE_WIDTH, MTG_MINIIMAGE_HEIGHT, "morph", RETRIEVE_MANAGE);
|
||||||
|
if (jq)
|
||||||
|
jq->SetHotSpot(static_cast<float> (jq->mTex->mWidth / 2), static_cast<float> (jq->mTex->mHeight / 2));
|
||||||
jq = WResourceManager::Instance()->RetrieveQuad("phasebar.png", 0, 0, 0, 0, "phasebar", RETRIEVE_MANAGE);
|
jq = WResourceManager::Instance()->RetrieveQuad("phasebar.png", 0, 0, 0, 0, "phasebar", RETRIEVE_MANAGE);
|
||||||
|
|
||||||
LOG("Init Collection");
|
LOG("Init Collection");
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ void GameObserver::nextGamePhase()
|
|||||||
currentPlayer->onlyoneinstant = false;
|
currentPlayer->onlyoneinstant = false;
|
||||||
currentPlayer->damageCount = 0;
|
currentPlayer->damageCount = 0;
|
||||||
currentPlayer->preventable = 0;
|
currentPlayer->preventable = 0;
|
||||||
|
currentPlayer->isPoisoned = false;
|
||||||
mLayers->actionLayer()->cleanGarbage(); //clean abilities history for this turn;
|
mLayers->actionLayer()->cleanGarbage(); //clean abilities history for this turn;
|
||||||
mLayers->stackLayer()->garbageCollect(); //clean stack history for this turn;
|
mLayers->stackLayer()->garbageCollect(); //clean stack history for this turn;
|
||||||
mLayers->actionLayer()->Update(0);
|
mLayers->actionLayer()->Update(0);
|
||||||
@@ -140,6 +141,8 @@ void GameObserver::nextGamePhase()
|
|||||||
while (currentPlayer->game->hand->nb_cards > 7 && currentPlayer->nomaxhandsize == false)
|
while (currentPlayer->game->hand->nb_cards > 7 && currentPlayer->nomaxhandsize == false)
|
||||||
currentPlayer->game->putInGraveyard(currentPlayer->game->hand->cards[0]);
|
currentPlayer->game->putInGraveyard(currentPlayer->game->hand->cards[0]);
|
||||||
mLayers->actionLayer()->Update(0);
|
mLayers->actionLayer()->Update(0);
|
||||||
|
currentPlayer->lifeLostThisTurn = 0;
|
||||||
|
currentPlayer->opponent()->lifeLostThisTurn = 0;
|
||||||
return nextGamePhase();
|
return nextGamePhase();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,6 +385,14 @@ void GameObserver::gameStateBasedEffects()
|
|||||||
{
|
{
|
||||||
players[i]->canPutLandsIntoPlay = true;
|
players[i]->canPutLandsIntoPlay = true;
|
||||||
}
|
}
|
||||||
|
if(players[i]->poisonCount > 0)
|
||||||
|
{
|
||||||
|
players[i]->isPoisoned = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
players[i]->isPoisoned = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (mLayers->stackLayer()->count(0, NOT_RESOLVED) != 0)
|
if (mLayers->stackLayer()->count(0, NOT_RESOLVED) != 0)
|
||||||
return;
|
return;
|
||||||
@@ -401,12 +412,77 @@ void GameObserver::gameStateBasedEffects()
|
|||||||
{
|
{
|
||||||
MTGCardInstance * card = zone->cards[j];
|
MTGCardInstance * card = zone->cards[j];
|
||||||
card->afterDamage();
|
card->afterDamage();
|
||||||
|
///////////////////////////////////////////////////////
|
||||||
//Remove auras that don't have a valid target anymore
|
//Remove auras that don't have a valid target anymore//
|
||||||
|
///////////////////////////////////////////////////////
|
||||||
if (card->target && !isInPlay(card->target) && !card->hasType("equipment"))
|
if (card->target && !isInPlay(card->target) && !card->hasType("equipment"))
|
||||||
{
|
{
|
||||||
players[i]->game->putInGraveyard(card);
|
players[i]->game->putInGraveyard(card);
|
||||||
}
|
}
|
||||||
|
card->enchanted = false;
|
||||||
|
if (card->target && isInPlay(card->target) && !card->hasType("equipment") && card->hasSubtype("aura"))
|
||||||
|
{
|
||||||
|
card->target->enchanted = true;
|
||||||
|
}
|
||||||
|
///////////////////////////
|
||||||
|
//reset extracost shadows//
|
||||||
|
///////////////////////////
|
||||||
|
card->isExtraCostTarget = false;
|
||||||
|
if(mExtraPayment != NULL)
|
||||||
|
{
|
||||||
|
for(unsigned int ec = 0;ec < mExtraPayment->costs.size();ec++)
|
||||||
|
{
|
||||||
|
if( mExtraPayment->costs[ec]->target)
|
||||||
|
mExtraPayment->costs[ec]->target->isExtraCostTarget = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//////////////////////
|
||||||
|
//reset morph hiding//
|
||||||
|
//////////////////////
|
||||||
|
if((card->previous && card->previous->morphed && !card->turningOver) || (card->morphed && !card->turningOver))
|
||||||
|
{
|
||||||
|
card->morphed = true;
|
||||||
|
card->isMorphed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
card->isMorphed = false;
|
||||||
|
card->morphed = false;
|
||||||
|
}
|
||||||
|
//////////////////////////
|
||||||
|
//handles phasing events//
|
||||||
|
//////////////////////////
|
||||||
|
if((card->has(Constants::PHASING)&& currentGamePhase == Constants::MTG_PHASE_UNTAP && currentPlayer == card->controller() && card->phasedTurn != turn && !card->isPhased) || (card->isTempPhased && !card->isPhased))
|
||||||
|
{
|
||||||
|
card->isPhased = true;
|
||||||
|
card->phasedTurn = turn;
|
||||||
|
if(card->view)
|
||||||
|
card->view->alpha = 50;
|
||||||
|
card->initAttackersDefensers();
|
||||||
|
}
|
||||||
|
else if((card->has(Constants::PHASING) || card->isTempPhased)&& currentGamePhase == Constants::MTG_PHASE_UNTAP && currentPlayer == card->controller() && card->phasedTurn != turn)
|
||||||
|
{
|
||||||
|
card->isPhased = false;
|
||||||
|
card->phasedTurn = turn;
|
||||||
|
if(card->view)
|
||||||
|
card->view->alpha = 255;
|
||||||
|
card->isTempPhased = false;
|
||||||
|
}
|
||||||
|
if (card->target && isInPlay(card->target) && (card->hasSubtype("equipment") || card->hasSubtype("aura")))
|
||||||
|
{
|
||||||
|
card->isPhased = card->target->isPhased;
|
||||||
|
card->phasedTurn = card->target->phasedTurn;
|
||||||
|
if(card->view && card->target->view)
|
||||||
|
card->view->alpha = card->target->view->alpha;
|
||||||
|
}
|
||||||
|
//////////////////////////
|
||||||
|
//forceDestroy over ride//
|
||||||
|
//////////////////////////
|
||||||
|
if(card->isInPlay())
|
||||||
|
{
|
||||||
|
card->graveEffects = false;
|
||||||
|
card->exileEffects = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
@@ -524,22 +600,22 @@ void GameObserver::gameStateBasedEffects()
|
|||||||
}
|
}
|
||||||
//------------------------------------
|
//------------------------------------
|
||||||
if (players[0]->bothrestrictedcreature)
|
if (players[0]->bothrestrictedcreature)
|
||||||
players[1]->castrestrictedcreature = true;
|
players[1]->castrestrictedcreature = true;
|
||||||
//------------------------------------
|
//------------------------------------
|
||||||
if (players[0]->bothrestrictedspell)
|
if (players[0]->bothrestrictedspell)
|
||||||
players[1]->castrestrictedspell = true;
|
players[1]->castrestrictedspell = true;
|
||||||
//------------------------------------
|
//------------------------------------
|
||||||
if (players[0]->onlyoneboth)
|
if (players[0]->onlyoneboth)
|
||||||
players[1]->onlyoneboth = true;
|
players[1]->onlyoneboth = true;
|
||||||
//------------------------------------
|
//------------------------------------
|
||||||
if (players[1]->bothrestrictedcreature)
|
if (players[1]->bothrestrictedcreature)
|
||||||
players[0]->castrestrictedcreature = true;
|
players[0]->castrestrictedcreature = true;
|
||||||
//------------------------------------
|
//------------------------------------
|
||||||
if (players[1]->bothrestrictedspell)
|
if (players[1]->bothrestrictedspell)
|
||||||
players[0]->castrestrictedspell = true;
|
players[0]->castrestrictedspell = true;
|
||||||
//------------------------------------
|
//------------------------------------
|
||||||
if (players[1]->onlyoneboth)
|
if (players[1]->onlyoneboth)
|
||||||
players[0]->onlyoneboth = true;
|
players[0]->onlyoneboth = true;
|
||||||
//------------------------------------
|
//------------------------------------
|
||||||
/////////////////////////////////////////////////
|
/////////////////////////////////////////////////
|
||||||
//handle end of turn effects while we're at it.//
|
//handle end of turn effects while we're at it.//
|
||||||
@@ -552,7 +628,10 @@ void GameObserver::gameStateBasedEffects()
|
|||||||
|
|
||||||
if(!c)break;
|
if(!c)break;
|
||||||
while (c->flanked)
|
while (c->flanked)
|
||||||
{//undoes the flanking on a card
|
{
|
||||||
|
/////////////////////////////////
|
||||||
|
//undoes the flanking on a card//
|
||||||
|
/////////////////////////////////
|
||||||
c->power += 1;
|
c->power += 1;
|
||||||
c->addToToughness(1);
|
c->addToToughness(1);
|
||||||
c->flanked -= 1;
|
c->flanked -= 1;
|
||||||
@@ -582,14 +661,13 @@ void GameObserver::gameStateBasedEffects()
|
|||||||
p->game->putInExile(c);
|
p->game->putInExile(c);
|
||||||
|
|
||||||
}
|
}
|
||||||
if(nbcards > z->nb_cards)
|
if(nbcards > z->nb_cards)
|
||||||
{
|
{
|
||||||
t = 0;
|
t = 0;
|
||||||
nbcards = z->nb_cards;
|
nbcards = z->nb_cards;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MTGGameZone * f = p->game->graveyard;
|
MTGGameZone * f = p->game->graveyard;
|
||||||
for (int k = 0; k < f->nb_cards; k++)
|
for (int k = 0; k < f->nb_cards; k++)
|
||||||
{
|
{
|
||||||
@@ -601,11 +679,55 @@ void GameObserver::gameStateBasedEffects()
|
|||||||
{
|
{
|
||||||
p->nomaxhandsize = false;
|
p->nomaxhandsize = false;
|
||||||
if (!p->bothrestrictedcreature && !p->opponent()->bothrestrictedcreature)
|
if (!p->bothrestrictedcreature && !p->opponent()->bothrestrictedcreature)
|
||||||
p->castrestrictedcreature = false;
|
p->castrestrictedcreature = false;
|
||||||
if (!p->bothrestrictedspell && !p->opponent()->bothrestrictedspell)
|
if (!p->bothrestrictedspell && !p->opponent()->bothrestrictedspell)
|
||||||
p->castrestrictedspell = false;
|
p->castrestrictedspell = false;
|
||||||
p->onlyonecast = false;
|
p->onlyonecast = false;
|
||||||
}
|
}
|
||||||
|
//////////////////////////
|
||||||
|
// Check auras on a card//
|
||||||
|
//////////////////////////
|
||||||
|
enchantmentStatus();
|
||||||
|
/////////////////////////////////////
|
||||||
|
// Check colored statuses on cards //
|
||||||
|
/////////////////////////////////////
|
||||||
|
for(int w = 0;w < z->nb_cards;w++)
|
||||||
|
{
|
||||||
|
int colored = 0;
|
||||||
|
for (int i = Constants::MTG_COLOR_GREEN; i <= Constants::MTG_COLOR_WHITE; ++i)
|
||||||
|
{
|
||||||
|
if (z->cards[w]->hasColor(i))
|
||||||
|
++colored;
|
||||||
|
}
|
||||||
|
if(colored > 1)
|
||||||
|
{
|
||||||
|
z->cards[w]->isMultiColored = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
z->cards[w]->isMultiColored = 0;
|
||||||
|
}
|
||||||
|
if(z->cards[w]->hasColor(Constants::MTG_COLOR_WHITE) && z->cards[w]->hasColor(Constants::MTG_COLOR_BLACK))
|
||||||
|
z->cards[w]->isBlackAndWhite = 1;
|
||||||
|
else
|
||||||
|
z->cards[w]->isBlackAndWhite = 0;
|
||||||
|
if(z->cards[w]->hasColor(Constants::MTG_COLOR_RED) && z->cards[w]->hasColor(Constants::MTG_COLOR_BLUE))
|
||||||
|
z->cards[w]->isRedAndBlue = 1;
|
||||||
|
else
|
||||||
|
z->cards[w]->isRedAndBlue = 0;
|
||||||
|
if(z->cards[w]->hasColor(Constants::MTG_COLOR_GREEN) && z->cards[w]->hasColor(Constants::MTG_COLOR_BLACK))
|
||||||
|
z->cards[w]->isBlackAndGreen = 1;
|
||||||
|
else
|
||||||
|
z->cards[w]->isBlackAndGreen = 0;
|
||||||
|
if(z->cards[w]->hasColor(Constants::MTG_COLOR_BLUE) && z->cards[w]->hasColor(Constants::MTG_COLOR_GREEN))
|
||||||
|
z->cards[w]->isBlueAndGreen = 1;
|
||||||
|
else
|
||||||
|
z->cards[w]->isBlueAndGreen = 0;
|
||||||
|
if(z->cards[w]->hasColor(Constants::MTG_COLOR_RED) && z->cards[w]->hasColor(Constants::MTG_COLOR_WHITE))
|
||||||
|
z->cards[w]->isRedAndWhite = 1;
|
||||||
|
else
|
||||||
|
z->cards[w]->isRedAndWhite = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
///////////////////////////////////
|
///////////////////////////////////
|
||||||
//phase based state effects------//
|
//phase based state effects------//
|
||||||
@@ -613,33 +735,58 @@ void GameObserver::gameStateBasedEffects()
|
|||||||
if (combatStep == TRIGGERS)
|
if (combatStep == TRIGGERS)
|
||||||
{
|
{
|
||||||
if (!mLayers->stackLayer()->getNext(NULL, 0, NOT_RESOLVED) && !targetChooser
|
if (!mLayers->stackLayer()->getNext(NULL, 0, NOT_RESOLVED) && !targetChooser
|
||||||
&& !mLayers->actionLayer()->isWaitingForAnswer())
|
&& !mLayers->actionLayer()->isWaitingForAnswer())
|
||||||
mLayers->stackLayer()->AddNextCombatStep();
|
mLayers->stackLayer()->AddNextCombatStep();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Auto skip Phases
|
//Auto skip Phases
|
||||||
GameObserver * game = game->GetInstance();
|
GameObserver * game = game->GetInstance();
|
||||||
int skipLevel = (game->currentPlayer->playMode == Player::MODE_TEST_SUITE) ? Constants::ASKIP_NONE
|
int skipLevel = (game->currentPlayer->playMode == Player::MODE_TEST_SUITE) ? Constants::ASKIP_NONE
|
||||||
: options[Options::ASPHASES].number;
|
: options[Options::ASPHASES].number;
|
||||||
int nrCreatures = currentPlayer->game->inPlay->countByType("Creature");
|
int nrCreatures = currentPlayer->game->inPlay->countByType("Creature");
|
||||||
|
|
||||||
if (skipLevel == Constants::ASKIP_SAFE || skipLevel == Constants::ASKIP_FULL)
|
if (skipLevel == Constants::ASKIP_SAFE || skipLevel == Constants::ASKIP_FULL)
|
||||||
{
|
{
|
||||||
if ((opponent()->isAI() && !(isInterrupting)) && ((currentGamePhase == Constants::MTG_PHASE_UNTAP)
|
if ((opponent()->isAI() && !(isInterrupting)) && ((currentGamePhase == Constants::MTG_PHASE_UNTAP)
|
||||||
|| (currentGamePhase == Constants::MTG_PHASE_DRAW) || (currentGamePhase == Constants::MTG_PHASE_COMBATBEGIN)
|
|| (currentGamePhase == Constants::MTG_PHASE_DRAW) || (currentGamePhase == Constants::MTG_PHASE_COMBATBEGIN)
|
||||||
|| ((currentGamePhase == Constants::MTG_PHASE_COMBATATTACKERS) && (nrCreatures == 0))
|
|| ((currentGamePhase == Constants::MTG_PHASE_COMBATATTACKERS) && (nrCreatures == 0))
|
||||||
|| currentGamePhase == Constants::MTG_PHASE_COMBATEND || currentGamePhase == Constants::MTG_PHASE_ENDOFTURN
|
|| currentGamePhase == Constants::MTG_PHASE_COMBATEND || currentGamePhase == Constants::MTG_PHASE_ENDOFTURN
|
||||||
|| ((currentGamePhase == Constants::MTG_PHASE_CLEANUP) && (currentPlayer->game->hand->nb_cards < 8))))
|
|| ((currentGamePhase == Constants::MTG_PHASE_CLEANUP) && (currentPlayer->game->hand->nb_cards < 8))))
|
||||||
userRequestNextGamePhase();
|
userRequestNextGamePhase();
|
||||||
}
|
}
|
||||||
if (skipLevel == Constants::ASKIP_FULL)
|
if (skipLevel == Constants::ASKIP_FULL)
|
||||||
{
|
{
|
||||||
if ((opponent()->isAI() && !(isInterrupting)) && (currentGamePhase == Constants::MTG_PHASE_UPKEEP
|
if ((opponent()->isAI() && !(isInterrupting)) && (currentGamePhase == Constants::MTG_PHASE_UPKEEP
|
||||||
|| currentGamePhase == Constants::MTG_PHASE_COMBATDAMAGE))
|
|| currentGamePhase == Constants::MTG_PHASE_COMBATDAMAGE))
|
||||||
userRequestNextGamePhase();
|
userRequestNextGamePhase();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameObserver::enchantmentStatus()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
MTGGameZone * zone = players[i]->game->inPlay;
|
||||||
|
for (int k = zone->nb_cards - 1; k >= 0; k--)
|
||||||
|
{
|
||||||
|
MTGCardInstance * card = zone->cards[k];
|
||||||
|
if (card && !card->hasType("equipment") && !card->hasSubtype("aura"))
|
||||||
|
{
|
||||||
|
card->enchanted = false;
|
||||||
|
card->auras = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int j = zone->nb_cards - 1; j >= 0; j--)
|
||||||
|
{
|
||||||
|
MTGCardInstance * card = zone->cards[j];
|
||||||
|
if (card->target && isInPlay(card->target) && !card->hasType("equipment") && card->hasSubtype("aura"))
|
||||||
|
{
|
||||||
|
card->target->enchanted = true;
|
||||||
|
card->target->auras += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
void GameObserver::Render()
|
void GameObserver::Render()
|
||||||
{
|
{
|
||||||
mLayers->Render();
|
mLayers->Render();
|
||||||
@@ -883,7 +1030,28 @@ int GameObserver::isInPlay(MTGCardInstance * card)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
int GameObserver::isInGrave(MTGCardInstance * card)
|
||||||
|
{
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
MTGGameZone * graveyard = players[i]->game->graveyard;
|
||||||
|
if (players[i]->game->isInZone(card,graveyard))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int GameObserver::isInExile(MTGCardInstance * card)
|
||||||
|
{
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
MTGGameZone * exile = players[i]->game->exile;
|
||||||
|
if (players[i]->game->isInZone(card,exile))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
void GameObserver::draw()
|
void GameObserver::draw()
|
||||||
{
|
{
|
||||||
currentPlayer->game->drawFromLibrary();
|
currentPlayer->game->drawFromLibrary();
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ const string Options::optionNames[] = {
|
|||||||
"disable_cards",
|
"disable_cards",
|
||||||
"maxGrade",
|
"maxGrade",
|
||||||
"ASPhases",
|
"ASPhases",
|
||||||
|
"FirstPlayer",
|
||||||
"economic_difficulty",
|
"economic_difficulty",
|
||||||
"transitions",
|
"transitions",
|
||||||
"bgStyle",
|
"bgStyle",
|
||||||
@@ -441,6 +442,11 @@ GameOption * GameOptions::get(int optionID)
|
|||||||
goEnum->def = OptionASkipPhase::getInstance();
|
goEnum->def = OptionASkipPhase::getInstance();
|
||||||
go = goEnum;
|
go = goEnum;
|
||||||
break;
|
break;
|
||||||
|
case Options::FIRSTPLAYER:
|
||||||
|
goEnum = NEW GameOptionEnum();
|
||||||
|
goEnum->def = OptionWhosFirst::getInstance();
|
||||||
|
go = goEnum;
|
||||||
|
break;
|
||||||
case Options::KEY_BINDINGS:
|
case Options::KEY_BINDINGS:
|
||||||
go = NEW GameOptionKeyBindings();
|
go = NEW GameOptionKeyBindings();
|
||||||
break;
|
break;
|
||||||
@@ -870,6 +876,16 @@ OptionASkipPhase::OptionASkipPhase()
|
|||||||
mDef.values.push_back(EnumDefinition::assoc(Constants::ASKIP_FULL, "Full"));
|
mDef.values.push_back(EnumDefinition::assoc(Constants::ASKIP_FULL, "Full"));
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
OptionWhosFirst OptionWhosFirst::mDef;
|
||||||
|
OptionWhosFirst::OptionWhosFirst()
|
||||||
|
{
|
||||||
|
mDef.values.push_back(EnumDefinition::assoc(Constants::WHO_P, "Player"));
|
||||||
|
mDef.values.push_back(EnumDefinition::assoc(Constants::WHO_O, "Opponent"));
|
||||||
|
mDef.values.push_back(EnumDefinition::assoc(Constants::WHO_R, "Random"));
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
OptionClosedHand OptionClosedHand::mDef;
|
OptionClosedHand OptionClosedHand::mDef;
|
||||||
OptionClosedHand::OptionClosedHand()
|
OptionClosedHand::OptionClosedHand()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -103,6 +103,10 @@ void GameStateOptions::Start()
|
|||||||
optionsList->Add(oASPhases);
|
optionsList->Add(oASPhases);
|
||||||
optionsTabs->Add(optionsList);
|
optionsTabs->Add(optionsList);
|
||||||
|
|
||||||
|
WDecoEnum * oFirstPlayer = NEW WDecoEnum(NEW OptionInteger(Options::FIRSTPLAYER, "First Turn Player", Constants::WHO_R, 1,
|
||||||
|
Constants::WHO_P, "", Constants::WHO_P));
|
||||||
|
optionsList->Add(oFirstPlayer);
|
||||||
|
|
||||||
optionsList = NEW WGuiKeyBinder("Key Bindings", this);
|
optionsList = NEW WGuiKeyBinder("Key Bindings", this);
|
||||||
optionsTabs->Add(optionsList);
|
optionsTabs->Add(optionsList);
|
||||||
|
|
||||||
|
|||||||
@@ -44,8 +44,11 @@ GuiHand::GuiHand(MTGHand* hand) :
|
|||||||
|
|
||||||
GuiHand::~GuiHand()
|
GuiHand::~GuiHand()
|
||||||
{
|
{
|
||||||
for (vector<CardView*>::iterator it = cards.begin(); it != cards.end(); ++it)
|
if(cards.size())
|
||||||
delete (*it);
|
{
|
||||||
|
for (vector<CardView*>::iterator it = cards.begin(); it != cards.end(); ++it)
|
||||||
|
delete (*it);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiHand::Update(float dt)
|
void GuiHand::Update(float dt)
|
||||||
|
|||||||
+913
-54
File diff suppressed because it is too large
Load Diff
@@ -31,6 +31,8 @@ MTGCardInstance::MTGCardInstance(MTGCard * card, MTGPlayerCards * arg_belongs_to
|
|||||||
model = card;
|
model = card;
|
||||||
attacker = 0;
|
attacker = 0;
|
||||||
lifeOrig = life;
|
lifeOrig = life;
|
||||||
|
origpower = power;
|
||||||
|
origtoughness = toughness;
|
||||||
belongs_to = arg_belongs_to;
|
belongs_to = arg_belongs_to;
|
||||||
owner = NULL;
|
owner = NULL;
|
||||||
if (arg_belongs_to)
|
if (arg_belongs_to)
|
||||||
@@ -69,7 +71,6 @@ void MTGCardInstance::copy(MTGCardInstance * card)
|
|||||||
toughness = data->toughness;
|
toughness = data->toughness;
|
||||||
life = toughness;
|
life = toughness;
|
||||||
lifeOrig = life;
|
lifeOrig = life;
|
||||||
|
|
||||||
magicText = data->magicText;
|
magicText = data->magicText;
|
||||||
spellTargetType = data->spellTargetType;
|
spellTargetType = data->spellTargetType;
|
||||||
alias = data->alias;
|
alias = data->alias;
|
||||||
@@ -109,6 +110,7 @@ void MTGCardInstance::initMTGCI()
|
|||||||
{
|
{
|
||||||
sample = "";
|
sample = "";
|
||||||
model = NULL;
|
model = NULL;
|
||||||
|
imprint = NULL;
|
||||||
isToken = false;
|
isToken = false;
|
||||||
lifeOrig = 0;
|
lifeOrig = 0;
|
||||||
doDamageTest = 1;
|
doDamageTest = 1;
|
||||||
@@ -117,11 +119,29 @@ void MTGCardInstance::initMTGCI()
|
|||||||
untapping = 0;
|
untapping = 0;
|
||||||
frozen = 0;
|
frozen = 0;
|
||||||
fresh = 0;
|
fresh = 0;
|
||||||
|
isMultiColored = 0;
|
||||||
|
isBlackAndWhite = 0;
|
||||||
|
isRedAndBlue = 0;
|
||||||
|
isBlackAndGreen = 0;
|
||||||
|
isBlueAndGreen = 0;
|
||||||
|
isRedAndWhite = 0;
|
||||||
|
isLeveler = 0;
|
||||||
|
enchanted = false;
|
||||||
|
CDenchanted = NULL;
|
||||||
|
blinked = false;
|
||||||
|
isExtraCostTarget = false;
|
||||||
|
morphed = false;
|
||||||
|
turningOver = false;
|
||||||
|
isMorphed = false;
|
||||||
|
isPhased = false;
|
||||||
|
isTempPhased = false;
|
||||||
|
phasedTurn = -1;
|
||||||
didattacked = 0;
|
didattacked = 0;
|
||||||
didblocked = 0;
|
didblocked = 0;
|
||||||
notblocked = 0;
|
notblocked = 0;
|
||||||
sunburst = NULL;
|
sunburst = NULL;
|
||||||
equipment = NULL;
|
equipment = 0;
|
||||||
|
auras = 0;
|
||||||
|
|
||||||
for (int i = 0; i < ManaCost::MANA_PAID_WITH_RETRACE +1; i++)
|
for (int i = 0; i < ManaCost::MANA_PAID_WITH_RETRACE +1; i++)
|
||||||
alternateCostPaid[i] = 0;
|
alternateCostPaid[i] = 0;
|
||||||
@@ -161,13 +181,39 @@ void MTGCardInstance::initMTGCI()
|
|||||||
s == "Dismiss" || s == "Equipment" || s == "Everglades" || s == "Grasslands" || s == "Lair" ||
|
s == "Dismiss" || s == "Equipment" || s == "Everglades" || s == "Grasslands" || s == "Lair" ||
|
||||||
s == "Level" || s == "Levelup" || s == "Mine" || s == "Oasis" || s == "World" || s == "Aura"
|
s == "Level" || s == "Levelup" || s == "Mine" || s == "Oasis" || s == "World" || s == "Aura"
|
||||||
)
|
)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
addType(i);
|
addType(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
int colored = 0;
|
||||||
|
|
||||||
|
for (int i = Constants::MTG_COLOR_GREEN; i <= Constants::MTG_COLOR_WHITE; ++i)
|
||||||
|
{
|
||||||
|
if (this->hasColor(i))
|
||||||
|
++colored;
|
||||||
|
}
|
||||||
|
if(colored > 1)
|
||||||
|
{
|
||||||
|
isMultiColored = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this->hasColor(Constants::MTG_COLOR_WHITE) && this->hasColor(Constants::MTG_COLOR_BLACK))
|
||||||
|
isBlackAndWhite = 1;
|
||||||
|
if(this->hasColor(Constants::MTG_COLOR_RED) && this->hasColor(Constants::MTG_COLOR_BLUE))
|
||||||
|
isRedAndBlue = 1;
|
||||||
|
if(this->hasColor(Constants::MTG_COLOR_GREEN) && this->hasColor(Constants::MTG_COLOR_BLACK))
|
||||||
|
isBlackAndGreen = 1;
|
||||||
|
if(this->hasColor(Constants::MTG_COLOR_BLUE) && this->hasColor(Constants::MTG_COLOR_GREEN))
|
||||||
|
isBlueAndGreen = 1;
|
||||||
|
if(this->hasColor(Constants::MTG_COLOR_RED) && this->hasColor(Constants::MTG_COLOR_WHITE))
|
||||||
|
isRedAndWhite = 1;
|
||||||
|
if(previous && previous->morphed == true && !turningOver)
|
||||||
|
{
|
||||||
|
morphed = true;
|
||||||
|
isMorphed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const string MTGCardInstance::getDisplayName() const
|
const string MTGCardInstance::getDisplayName() const
|
||||||
@@ -529,6 +575,10 @@ int MTGCardInstance::canBlock(MTGCardInstance * opponent)
|
|||||||
return 0;
|
return 0;
|
||||||
if (opponent->basicAbilities[Constants::ONEBLOCKER] && opponent->blocked)
|
if (opponent->basicAbilities[Constants::ONEBLOCKER] && opponent->blocked)
|
||||||
return 0;
|
return 0;
|
||||||
|
if(opponent->basicAbilities[Constants::STRONG] && power < opponent->power)
|
||||||
|
return 0;
|
||||||
|
if(has(basicAbilities[Constants::WEAK]) && power < opponent->power)
|
||||||
|
return 0;
|
||||||
if (opponent->basicAbilities[Constants::FEAR] && !(hasType(Subtypes::TYPE_ARTIFACT) || hasColor(Constants::MTG_COLOR_BLACK)))
|
if (opponent->basicAbilities[Constants::FEAR] && !(hasType(Subtypes::TYPE_ARTIFACT) || hasColor(Constants::MTG_COLOR_BLACK)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -572,6 +622,24 @@ int MTGCardInstance::canBlock(MTGCardInstance * opponent)
|
|||||||
return 0;
|
return 0;
|
||||||
if (opponent->basicAbilities[Constants::PLAINSWALK] && controller()->game->inPlay->hasType("plains"))
|
if (opponent->basicAbilities[Constants::PLAINSWALK] && controller()->game->inPlay->hasType("plains"))
|
||||||
return 0;
|
return 0;
|
||||||
|
if (opponent->basicAbilities[Constants::LEGENDARYWALK] && controller()->game->inPlay->hasPrimaryType("legendary","land"))
|
||||||
|
return 0;
|
||||||
|
if (opponent->basicAbilities[Constants::DESERTWALK] && controller()->game->inPlay->hasSpecificType("land","desert"))
|
||||||
|
return 0;
|
||||||
|
if (opponent->basicAbilities[Constants::SNOWSWAMPWALK] && controller()->game->inPlay->hasSpecificType("snow","swamp"))
|
||||||
|
return 0;
|
||||||
|
if (opponent->basicAbilities[Constants::SNOWFORESTWALK] && controller()->game->inPlay->hasSpecificType("snow","forest"))
|
||||||
|
return 0;
|
||||||
|
if (opponent->basicAbilities[Constants::SNOWISLANDWALK] && controller()->game->inPlay->hasSpecificType("snow","island"))
|
||||||
|
return 0;
|
||||||
|
if (opponent->basicAbilities[Constants::SNOWMOUNTAINWALK] && controller()->game->inPlay->hasSpecificType("snow","mountain"))
|
||||||
|
return 0;
|
||||||
|
if (opponent->basicAbilities[Constants::SNOWPLAINSWALK] && controller()->game->inPlay->hasSpecificType("snow","plains"))
|
||||||
|
return 0;
|
||||||
|
if (opponent->basicAbilities[Constants::SNOWWALK] && controller()->game->inPlay->hasPrimaryType("snow","land"))
|
||||||
|
return 0;
|
||||||
|
if (opponent->basicAbilities[Constants::NONBASICWALK] && controller()->game->inPlay->hasTypeButNotType("land","basic"))
|
||||||
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -138,12 +138,21 @@ int MTGAllCards::processConfLine(string &s, MTGCard *card, CardPrimitive * primi
|
|||||||
|
|
||||||
case 'o': //othercost
|
case 'o': //othercost
|
||||||
if (!primitive) primitive = NEW CardPrimitive();
|
if (!primitive) primitive = NEW CardPrimitive();
|
||||||
|
if(key[5] == 'r')//otherrestrictions
|
||||||
|
{
|
||||||
|
string value = val;
|
||||||
|
primitive->setOtherRestrictions(value);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (ManaCost * cost = primitive->getManaCost())
|
if (ManaCost * cost = primitive->getManaCost())
|
||||||
{
|
{
|
||||||
string value = val;
|
string value = val;
|
||||||
std::transform(value.begin(), value.end(), value.begin(), ::tolower);
|
std::transform(value.begin(), value.end(), value.begin(), ::tolower);
|
||||||
cost->alternative = ManaCost::parseManaCost(value);
|
cost->alternative = ManaCost::parseManaCost(value);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'b': //buyback
|
case 'b': //buyback
|
||||||
@@ -155,16 +164,26 @@ int MTGAllCards::processConfLine(string &s, MTGCard *card, CardPrimitive * primi
|
|||||||
cost->BuyBack = ManaCost::parseManaCost(value);
|
cost->BuyBack = ManaCost::parseManaCost(value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'f': //flashback
|
case 'f': //flashback//morph
|
||||||
if (!primitive) primitive = NEW CardPrimitive();
|
|
||||||
if (ManaCost * cost = primitive->getManaCost())
|
|
||||||
{
|
{
|
||||||
string value = val;
|
if (!primitive) primitive = NEW CardPrimitive();
|
||||||
std::transform(value.begin(), value.end(), value.begin(), ::tolower);
|
if(ManaCost * cost = primitive->getManaCost())
|
||||||
cost->FlashBack = ManaCost::parseManaCost(value);
|
{
|
||||||
|
if( s.find("facedown") != string::npos)//morph
|
||||||
|
{
|
||||||
|
string value = val;
|
||||||
|
std::transform(value.begin(), value.end(), value.begin(), ::tolower);
|
||||||
|
cost->morph = ManaCost::parseManaCost(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string value = val;
|
||||||
|
std::transform(value.begin(), value.end(), value.begin(), ::tolower);
|
||||||
|
cost->FlashBack = ManaCost::parseManaCost(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case 'i': //id
|
case 'i': //id
|
||||||
if (!card) card = NEW MTGCard();
|
if (!card) card = NEW MTGCard();
|
||||||
card->setMTGId(atoi(val));
|
card->setMTGId(atoi(val));
|
||||||
@@ -200,7 +219,61 @@ int MTGAllCards::processConfLine(string &s, MTGCard *card, CardPrimitive * primi
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'r': //retrace/rarity
|
case 'r': //retrace/rarity
|
||||||
if ('e' == key[1])
|
if('s' == key[2])//restrictions
|
||||||
|
{
|
||||||
|
if (!primitive) primitive = NEW CardPrimitive();
|
||||||
|
string value = val;
|
||||||
|
primitive->setRestrictions(CardPrimitive::NO_RESTRICTION);
|
||||||
|
primitive->hasRestriction = false;
|
||||||
|
if (value.find("control two or more vampires") != string::npos)
|
||||||
|
primitive->setRestrictions(CardPrimitive::VAMPIRES);
|
||||||
|
if (value.find("control less creatures") != string::npos)
|
||||||
|
primitive->setRestrictions(CardPrimitive::LESS_CREATURES);
|
||||||
|
if (value.find("control snow land") != string::npos)
|
||||||
|
primitive->setRestrictions(CardPrimitive::SNOW_LAND_INPLAY);
|
||||||
|
if (value.find("casted a spell") != string::npos)
|
||||||
|
primitive->setRestrictions(CardPrimitive::CASTED_A_SPELL);
|
||||||
|
if (value.find("one of a kind") != string::npos)
|
||||||
|
primitive->setRestrictions(CardPrimitive::ONE_OF_AKIND);
|
||||||
|
if (value.find("fourth turn") != string::npos)
|
||||||
|
primitive->setRestrictions(CardPrimitive::FOURTHTURN);
|
||||||
|
if (value.find("before battle damage") != string::npos)
|
||||||
|
primitive->setRestrictions(CardPrimitive::BEFORECOMBATDAMAGE);
|
||||||
|
if (value.find("after battle") != string::npos)
|
||||||
|
primitive->setRestrictions(CardPrimitive::AFTERCOMBAT);
|
||||||
|
if (value.find("during battle") != string::npos)
|
||||||
|
primitive->setRestrictions(CardPrimitive::DURINGCOMBAT);
|
||||||
|
if (value.find("myturnonly") != string::npos)
|
||||||
|
primitive->setRestrictions(CardPrimitive::PLAYER_TURN_ONLY);
|
||||||
|
if (value.find("opponentturnonly") != string::npos)
|
||||||
|
primitive->setRestrictions(CardPrimitive::OPPONENT_TURN_ONLY);
|
||||||
|
if (value.find("assorcery") != string::npos)
|
||||||
|
primitive->setRestrictions(CardPrimitive::AS_SORCERY);
|
||||||
|
string types[] = { "my", "opponent", "" };
|
||||||
|
int starts[] = { CardPrimitive::MY_BEFORE_BEGIN, CardPrimitive::OPPONENT_BEFORE_BEGIN, CardPrimitive::BEFORE_BEGIN };
|
||||||
|
for (int j = 0; j < 3; ++j)
|
||||||
|
{
|
||||||
|
size_t found = value.find(types[j]);
|
||||||
|
if (found != string::npos)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Constants::NB_MTG_PHASES; i++)
|
||||||
|
{
|
||||||
|
string toFind = types[j];
|
||||||
|
toFind.append(Constants::MTGPhaseCodeNames[i]).append("only");
|
||||||
|
found = value.find(toFind);
|
||||||
|
if (found != string::npos)
|
||||||
|
{
|
||||||
|
if(primitive->hasRestriction == false)
|
||||||
|
{
|
||||||
|
primitive->setRestrictions(starts[j] + i);
|
||||||
|
primitive->hasRestriction = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ('e' == key[1])
|
||||||
{ //retrace
|
{ //retrace
|
||||||
if (!primitive) primitive = NEW CardPrimitive();
|
if (!primitive) primitive = NEW CardPrimitive();
|
||||||
if (ManaCost * cost = primitive->getManaCost())
|
if (ManaCost * cost = primitive->getManaCost())
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ const string Constants::kBuyBackKeyword = "buyback";
|
|||||||
const string Constants::kFlashBackKeyword = "flashback";
|
const string Constants::kFlashBackKeyword = "flashback";
|
||||||
const string Constants::kRetraceKeyword = "retrace";
|
const string Constants::kRetraceKeyword = "retrace";
|
||||||
const string Constants::kKickerKeyword = "kicker";
|
const string Constants::kKickerKeyword = "kicker";
|
||||||
|
const string Constants::kMorphKeyword = "facedown";
|
||||||
|
|
||||||
const char* Constants::MTGBasicAbilities[] = {
|
const char* Constants::MTGBasicAbilities[] = {
|
||||||
"trample",
|
"trample",
|
||||||
@@ -110,6 +111,18 @@ const char* Constants::MTGBasicAbilities[] = {
|
|||||||
"sunburst",
|
"sunburst",
|
||||||
"flanking",
|
"flanking",
|
||||||
"exiledeath",
|
"exiledeath",
|
||||||
|
"legendarylandwalk",
|
||||||
|
"desertlandwalk",
|
||||||
|
"snowforestlandwalk",
|
||||||
|
"snowplainslandwalk",
|
||||||
|
"snowmountainlandwalk",
|
||||||
|
"snowislandlandwalk",
|
||||||
|
"snowswamplandwalk",
|
||||||
|
"snowlandwalk",
|
||||||
|
"nonbasiclandwalk",
|
||||||
|
"strong",//cant be blocked by creature with less power
|
||||||
|
"weak",//cant block creatures with more power
|
||||||
|
"phasing",
|
||||||
};
|
};
|
||||||
|
|
||||||
map<string,int> Constants::MTGBasicAbilitiesMap;
|
map<string,int> Constants::MTGBasicAbilitiesMap;
|
||||||
|
|||||||
@@ -275,6 +275,10 @@ MTGCardInstance * MTGPlayerCards::putInExile(MTGCardInstance * card)
|
|||||||
{
|
{
|
||||||
copy = putInZone(card, stack, exile);
|
copy = putInZone(card, stack, exile);
|
||||||
}
|
}
|
||||||
|
else if (hand->hasCard(card))
|
||||||
|
{
|
||||||
|
copy = putInZone(card, hand, exile);
|
||||||
|
}
|
||||||
else if (graveyard->hasCard(card))
|
else if (graveyard->hasCard(card))
|
||||||
{
|
{
|
||||||
copy = putInZone(card, graveyard, exile);
|
copy = putInZone(card, graveyard, exile);
|
||||||
@@ -325,6 +329,10 @@ MTGCardInstance * MTGPlayerCards::putInHand(MTGCardInstance * card)
|
|||||||
{
|
{
|
||||||
copy = putInZone(card, graveyard, hand);
|
copy = putInZone(card, graveyard, hand);
|
||||||
}
|
}
|
||||||
|
else if (exile->hasCard(card))
|
||||||
|
{
|
||||||
|
copy = putInZone(card, exile, hand);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
copy = putInZone(card, hand, hand);
|
copy = putInZone(card, hand, hand);
|
||||||
@@ -332,6 +340,33 @@ MTGCardInstance * MTGPlayerCards::putInHand(MTGCardInstance * card)
|
|||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MTGCardInstance * MTGPlayerCards::putInBattlefield(MTGCardInstance * card)
|
||||||
|
{
|
||||||
|
MTGCardInstance * copy = NULL;
|
||||||
|
MTGInPlay * InPlay = card->owner->game->battlefield;
|
||||||
|
if (inPlay->hasCard(card))
|
||||||
|
{
|
||||||
|
copy = putInZone(card, inPlay, InPlay);
|
||||||
|
}
|
||||||
|
else if (stack->hasCard(card))
|
||||||
|
{
|
||||||
|
copy = putInZone(card, stack, InPlay);
|
||||||
|
}
|
||||||
|
else if (graveyard->hasCard(card))
|
||||||
|
{
|
||||||
|
copy = putInZone(card, graveyard, InPlay);
|
||||||
|
}
|
||||||
|
else if (exile->hasCard(card))
|
||||||
|
{
|
||||||
|
copy = putInZone(card, exile, InPlay);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
copy = putInZone(card, InPlay, InPlay);
|
||||||
|
}
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone * from, MTGGameZone * to)
|
MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone * from, MTGGameZone * to)
|
||||||
{
|
{
|
||||||
MTGCardInstance * copy = NULL;
|
MTGCardInstance * copy = NULL;
|
||||||
@@ -420,7 +455,14 @@ int MTGPlayerCards::isInPlay(MTGCardInstance * card)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
int MTGPlayerCards::isInZone(MTGCardInstance * card,MTGGameZone * zone)
|
||||||
|
{
|
||||||
|
if (zone->hasCard(card))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
//--------------------------------------
|
//--------------------------------------
|
||||||
// Zones specific code
|
// Zones specific code
|
||||||
//--------------------------------------
|
//--------------------------------------
|
||||||
@@ -537,6 +579,54 @@ int MTGGameZone::hasType(const char * value)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int MTGGameZone::hasPrimaryType(const char * value,const char * secondvalue)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < (nb_cards); i++)
|
||||||
|
{
|
||||||
|
if (cards[i]->hasType(value) && cards[i]->hasType(secondvalue))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MTGGameZone::hasSpecificType(const char * value,const char * secondvalue)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < (nb_cards); i++)
|
||||||
|
{
|
||||||
|
if (cards[i]->hasType(value) && cards[i]->hasSubtype(secondvalue))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MTGGameZone::hasTypeButNotType(const char * value,const char * secondvalue)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < (nb_cards); i++)
|
||||||
|
{
|
||||||
|
if (cards[i]->hasType(value) && cards[i]->hasSubtype(value) && !cards[i]->hasType(secondvalue) && !cards[i]->hasSubtype(secondvalue))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MTGGameZone::hasName(string value)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < (nb_cards); i++)
|
||||||
|
{
|
||||||
|
if (cards[i]->name == value)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int MTGGameZone::hasColor(int value)
|
int MTGGameZone::hasColor(int value)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < (nb_cards); i++)
|
for (int i = 0; i < (nb_cards); i++)
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ int MTGPutInPlayRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if(!allowedToCast(card,player))
|
||||||
|
return 0;
|
||||||
if (card->hasType("land"))
|
if (card->hasType("land"))
|
||||||
{
|
{
|
||||||
if (player == currentPlayer && currentPlayer->canPutLandsIntoPlay
|
if (player == currentPlayer && currentPlayer->canPutLandsIntoPlay
|
||||||
@@ -44,7 +46,7 @@ int MTGPutInPlayRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((card->hasType("instant")) || card->has(Constants::FLASH)
|
else if ((card->hasType("instant")) || card->basicAbilities[Constants::FLASH]
|
||||||
|| (player == currentPlayer && !game->isInterrupting
|
|| (player == currentPlayer && !game->isInterrupting
|
||||||
&& (game->currentGamePhase == Constants::MTG_PHASE_FIRSTMAIN
|
&& (game->currentGamePhase == Constants::MTG_PHASE_FIRSTMAIN
|
||||||
|| game->currentGamePhase == Constants::MTG_PHASE_SECONDMAIN))
|
|| game->currentGamePhase == Constants::MTG_PHASE_SECONDMAIN))
|
||||||
@@ -250,6 +252,11 @@ int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *
|
|||||||
if (!alternateManaCost)
|
if (!alternateManaCost)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if(!allowedToCast(card,player))
|
||||||
|
return 0;
|
||||||
|
if(!allowedToAltCast(card,player))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (card->hasType("land"))
|
if (card->hasType("land"))
|
||||||
{
|
{
|
||||||
if (player == currentPlayer && currentPlayer->canPutLandsIntoPlay
|
if (player == currentPlayer && currentPlayer->canPutLandsIntoPlay
|
||||||
@@ -356,7 +363,7 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card, ManaCost *alter
|
|||||||
|
|
||||||
if (card->hasType("land"))
|
if (card->hasType("land"))
|
||||||
{
|
{
|
||||||
MTGCardInstance * copy = player->game->putInZone(card, player->game->hand, player->game->temp);
|
MTGCardInstance * copy = player->game->putInZone(card, card->currentZone, player->game->temp);
|
||||||
spell = NEW Spell(copy);
|
spell = NEW Spell(copy);
|
||||||
copy->alternateCostPaid[alternateCostType] = 1;
|
copy->alternateCostPaid[alternateCostType] = 1;
|
||||||
spell->resolve();
|
spell->resolve();
|
||||||
@@ -368,7 +375,7 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card, ManaCost *alter
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ManaCost *spellCost = previousManaPool->Diff(player->getManaPool());
|
ManaCost *spellCost = previousManaPool->Diff(player->getManaPool());
|
||||||
MTGCardInstance * copy = player->game->putInZone(card, originatingZone, player->game->stack);
|
MTGCardInstance * copy = player->game->putInZone(card, card->currentZone, player->game->stack);
|
||||||
copy->alternateCostPaid[alternateCostType] = 1;
|
copy->alternateCostPaid[alternateCostType] = 1;
|
||||||
spell = game->mLayers->stackLayer()->addSpell(copy, game->targetChooser, spellCost, payResult, 0);
|
spell = game->mLayers->stackLayer()->addSpell(copy, game->targetChooser, spellCost, payResult, 0);
|
||||||
game->targetChooser = NULL;
|
game->targetChooser = NULL;
|
||||||
@@ -431,6 +438,8 @@ MTGAlternativeCostRule(_id)
|
|||||||
int MTGBuyBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
|
int MTGBuyBackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
|
||||||
{
|
{
|
||||||
Player * player = game->currentlyActing();
|
Player * player = game->currentlyActing();
|
||||||
|
if(!allowedToCast(card,player))
|
||||||
|
return 0;
|
||||||
if (!player->game->hand->hasCard(card))
|
if (!player->game->hand->hasCard(card))
|
||||||
return 0;
|
return 0;
|
||||||
return MTGAlternativeCostRule::isReactingToClick( card, mana, card->getManaCost()->BuyBack );
|
return MTGAlternativeCostRule::isReactingToClick( card, mana, card->getManaCost()->BuyBack );
|
||||||
@@ -584,13 +593,179 @@ MTGRetraceRule * MTGRetraceRule::clone() const
|
|||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
//-----------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
MTGMorphCostRule::MTGMorphCostRule(int _id) :
|
||||||
|
MTGAbility(_id, NULL)
|
||||||
|
{
|
||||||
|
aType = MTGAbility::MORPH_COST;
|
||||||
|
}
|
||||||
|
int MTGMorphCostRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
|
||||||
|
{
|
||||||
|
int cardsinhand = game->players[0]->game->hand->nb_cards;
|
||||||
|
Player * player = game->currentlyActing();
|
||||||
|
Player * currentPlayer = game->currentPlayer;
|
||||||
|
if (!player->game->hand->hasCard(card))
|
||||||
|
return 0;
|
||||||
|
if (!card->getManaCost()->morph)
|
||||||
|
return 0;
|
||||||
|
if(!allowedToCast(card,player))
|
||||||
|
return 0;
|
||||||
|
if(!allowedToAltCast(card,player))
|
||||||
|
return 0;
|
||||||
|
//note lands can morph too, this is different from other cost types.
|
||||||
|
if ((card->hasType("instant")) || card->has(Constants::FLASH) || (player == currentPlayer
|
||||||
|
&& !game->isInterrupting
|
||||||
|
&& (game->currentGamePhase == Constants::MTG_PHASE_FIRSTMAIN
|
||||||
|
|| game->currentGamePhase == Constants::MTG_PHASE_SECONDMAIN))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ManaCost * playerMana = player->getManaPool();
|
||||||
|
ManaCost * cost = card->getManaCost();
|
||||||
|
ManaCost * morph = card->getManaCost()->morph;
|
||||||
|
#ifdef WIN32
|
||||||
|
cost->Dump();
|
||||||
|
#endif
|
||||||
|
if (player->castrestrictedspell == true && !card->hasType("land"))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (player->onlyonecast == true && player->castcount >= 1)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (player->nospellinstant == true)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (player->onlyoneinstant == true)
|
||||||
|
{
|
||||||
|
if (player->castcount >= 1)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (player->nocreatureinstant == true && card->hasType("creature"))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (player->castrestrictedcreature == true && card->hasType("creature"))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
//cost of card.
|
||||||
|
if (morph && playerMana->canAfford(morph))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;//dont play if you cant afford it.
|
||||||
|
}
|
||||||
|
|
||||||
|
int MTGMorphCostRule::reactToClick(MTGCardInstance * card)
|
||||||
|
{
|
||||||
|
//morphs reactToClick is extremely different then the other cost.
|
||||||
|
if (!isReactingToClick(card))
|
||||||
|
return 0;
|
||||||
|
Player * player = game->currentlyActing();
|
||||||
|
ManaCost * cost = card->getManaCost();
|
||||||
|
ManaCost * morph = card->getManaCost()->morph;
|
||||||
|
ManaCost * playerMana = player->getManaPool();
|
||||||
|
//this handles extra cost payments at the moment a card is played.
|
||||||
|
if (playerMana->canAfford(morph))
|
||||||
|
{
|
||||||
|
if (cost->morph->isExtraPaymentSet())
|
||||||
|
{
|
||||||
|
card->paymenttype = MTGAbility::MORPH_COST;
|
||||||
|
if (!game->targetListIsSet(card))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cost->morph->setExtraCostsAction(this, card);
|
||||||
|
game->mExtraPayment = cost->morph->extraCosts;
|
||||||
|
card->paymenttype = MTGAbility::MORPH_COST;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
ManaCost * previousManaPool = NEW ManaCost(player->getManaPool());
|
||||||
|
int payResult = player->getManaPool()->pay(card->getManaCost()->morph);
|
||||||
|
card->getManaCost()->morph->doPayExtra();
|
||||||
|
payResult = ManaCost::MANA_PAID_WITH_MORPH;
|
||||||
|
//if morph has a extra payment thats set, this code pays it.the if statement is 100% needed as it would cause a crash on cards that dont have the morph cost.
|
||||||
|
if (morph)
|
||||||
|
{
|
||||||
|
card->getManaCost()->morph->doPayExtra();
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
ManaCost * spellCost = previousManaPool->Diff(player->getManaPool());
|
||||||
|
delete previousManaPool;
|
||||||
|
card->morphed = true;
|
||||||
|
card->isMorphed = true;
|
||||||
|
MTGCardInstance * copy = player->game->putInZone(card, card->currentZone, player->game->stack);
|
||||||
|
Spell * spell = NULL;
|
||||||
|
spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, payResult, 0);
|
||||||
|
spell->source->morphed = true;
|
||||||
|
spell->source->isMorphed = true;
|
||||||
|
spell->source->name = "";
|
||||||
|
spell->source->power = 2;
|
||||||
|
spell->source->toughness = 2;
|
||||||
|
copy->morphed = true;
|
||||||
|
copy->isMorphed = true;
|
||||||
|
copy->power = 2;
|
||||||
|
copy->toughness = 2;
|
||||||
|
player->castedspellsthisturn += 1;
|
||||||
|
player->opponent()->castedspellsthisturn += 1;
|
||||||
|
if (player->onlyonecast == true || player->onlyoneinstant == true)
|
||||||
|
{
|
||||||
|
player->castcount += 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (!card->has(Constants::STORM))
|
||||||
|
{
|
||||||
|
copy->X = spell->computeX(copy);
|
||||||
|
copy->XX = spell->computeXX(copy);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//The morph rule is never destroyed
|
||||||
|
int MTGMorphCostRule::testDestroy()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ostream& MTGMorphCostRule::toString(ostream& out) const
|
||||||
|
{
|
||||||
|
out << "MTGMorphCostRule ::: (";
|
||||||
|
return MTGAbility::toString(out) << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
MTGMorphCostRule * MTGMorphCostRule::clone() const
|
||||||
|
{
|
||||||
|
MTGMorphCostRule * a = NEW MTGMorphCostRule(*this);
|
||||||
|
a->isClone = 1;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool MTGAttackRule::select(Target* t)
|
bool MTGAttackRule::select(Target* t)
|
||||||
{
|
{
|
||||||
if (CardView* c = dynamic_cast<CardView*>(t))
|
if (CardView* c = dynamic_cast<CardView*>(t))
|
||||||
{
|
{
|
||||||
MTGCardInstance * card = c->getCard();
|
MTGCardInstance * card = c->getCard();
|
||||||
if (card->canAttack())
|
if (card->canAttack() && !card->isPhased)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -610,6 +785,8 @@ int MTGAttackRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
|
|||||||
{
|
{
|
||||||
if (currentPhase == Constants::MTG_PHASE_COMBATATTACKERS && card->controller() == game->currentPlayer)
|
if (currentPhase == Constants::MTG_PHASE_COMBATATTACKERS && card->controller() == game->currentPlayer)
|
||||||
{
|
{
|
||||||
|
if(card->isPhased)
|
||||||
|
return 0;
|
||||||
if (card->isAttacker())
|
if (card->isAttacker())
|
||||||
return 1;
|
return 1;
|
||||||
if (card->canAttack())
|
if (card->canAttack())
|
||||||
@@ -845,7 +1022,7 @@ int MTGBlockRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
|
|||||||
&& card->controller() == game->currentlyActing()
|
&& card->controller() == game->currentlyActing()
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (card->canBlock())
|
if (card->canBlock() && !card->isPhased)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1620,6 +1797,8 @@ ListMaintainerAbility(_id)
|
|||||||
|
|
||||||
int MTGLegendRule::canBeInList(MTGCardInstance * card)
|
int MTGLegendRule::canBeInList(MTGCardInstance * card)
|
||||||
{
|
{
|
||||||
|
if(card->isPhased)
|
||||||
|
return 0;
|
||||||
if (card->hasType(Subtypes::TYPE_LEGENDARY) && game->isInPlay(card))
|
if (card->hasType(Subtypes::TYPE_LEGENDARY) && game->isInPlay(card))
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
@@ -1684,6 +1863,11 @@ int MTGLifelinkRule::receiveEvent(WEvent * event)
|
|||||||
MTGCardInstance * card = d->source;
|
MTGCardInstance * card = d->source;
|
||||||
if (d->damage > 0 && card && card->basicAbilities[Constants::LIFELINK])
|
if (d->damage > 0 && card && card->basicAbilities[Constants::LIFELINK])
|
||||||
{
|
{
|
||||||
|
card->controller()->thatmuch = d->damage;
|
||||||
|
WEvent * lifed = NULL;
|
||||||
|
lifed = NEW WEventLife(card->controller(),d->damage);
|
||||||
|
GameObserver * game = GameObserver::GetInstance();
|
||||||
|
game->receiveEvent(lifed);
|
||||||
card->controller()->life += d->damage;
|
card->controller()->life += d->damage;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -251,13 +251,13 @@ ManaCost::~ManaCost()
|
|||||||
{
|
{
|
||||||
SAFE_DELETE(hybrids[i]);
|
SAFE_DELETE(hybrids[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
SAFE_DELETE(extraCosts);
|
SAFE_DELETE(extraCosts);
|
||||||
SAFE_DELETE(kicker);
|
SAFE_DELETE(kicker);
|
||||||
SAFE_DELETE(alternative);
|
SAFE_DELETE(alternative);
|
||||||
SAFE_DELETE(BuyBack);
|
SAFE_DELETE(BuyBack);
|
||||||
SAFE_DELETE(FlashBack);
|
SAFE_DELETE(FlashBack);
|
||||||
SAFE_DELETE(Retrace);
|
SAFE_DELETE(Retrace);
|
||||||
|
SAFE_DELETE(morph);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ManaCost::x()
|
void ManaCost::x()
|
||||||
@@ -285,6 +285,7 @@ void ManaCost::init()
|
|||||||
BuyBack = NULL;
|
BuyBack = NULL;
|
||||||
FlashBack = NULL;
|
FlashBack = NULL;
|
||||||
Retrace = NULL;
|
Retrace = NULL;
|
||||||
|
morph = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ManaCost::copy(ManaCost * _manaCost)
|
void ManaCost::copy(ManaCost * _manaCost)
|
||||||
@@ -341,6 +342,12 @@ void ManaCost::copy(ManaCost * _manaCost)
|
|||||||
Retrace = NEW ManaCost();
|
Retrace = NEW ManaCost();
|
||||||
Retrace->copy(_manaCost->Retrace);
|
Retrace->copy(_manaCost->Retrace);
|
||||||
}
|
}
|
||||||
|
SAFE_DELETE(morph);
|
||||||
|
if (_manaCost->morph)
|
||||||
|
{
|
||||||
|
morph = NEW ManaCost();
|
||||||
|
morph->copy(_manaCost->morph);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ManaCost::getCost(int color)
|
int ManaCost::getCost(int color)
|
||||||
|
|||||||
@@ -378,6 +378,16 @@ void Rules::initGame()
|
|||||||
DebugTrace("RULES Init Game\n");
|
DebugTrace("RULES Init Game\n");
|
||||||
|
|
||||||
//Set the current player/phase
|
//Set the current player/phase
|
||||||
|
if (g->currentPlayer->playMode
|
||||||
|
!= Player::MODE_TEST_SUITE && /*g->mRules->gamemode != GAME_TYPE_MOMIR && g->mRules->gamemode
|
||||||
|
!= GAME_TYPE_RANDOM1 && g->mRules->gamemode != GAME_TYPE_RANDOM2 &&*/ g->mRules->gamemode
|
||||||
|
!= GAME_TYPE_STORY)
|
||||||
|
{
|
||||||
|
if(OptionWhosFirst::WHO_R == options[Options::FIRSTPLAYER].number)
|
||||||
|
initState.player = WRand() % 2;
|
||||||
|
if(OptionWhosFirst::WHO_O == options[Options::FIRSTPLAYER].number)
|
||||||
|
initState.player = 1;
|
||||||
|
}
|
||||||
g->currentPlayer = g->players[initState.player];
|
g->currentPlayer = g->players[initState.player];
|
||||||
g->currentActionPlayer = g->currentPlayer;
|
g->currentActionPlayer = g->currentPlayer;
|
||||||
g->currentPlayerId = initState.player;
|
g->currentPlayerId = initState.player;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "Subtypes.h"
|
#include "Subtypes.h"
|
||||||
#include "Counters.h"
|
#include "Counters.h"
|
||||||
#include "WEvent.h"
|
#include "WEvent.h"
|
||||||
|
#include "AllAbilities.h"
|
||||||
|
|
||||||
TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInstance * card, MTGAbility * ability)
|
TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInstance * card, MTGAbility * ability)
|
||||||
{
|
{
|
||||||
@@ -153,8 +154,23 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta
|
|||||||
TargetChooser * tc = NULL;
|
TargetChooser * tc = NULL;
|
||||||
int maxtargets = 1;
|
int maxtargets = 1;
|
||||||
CardDescriptor * cd = NULL;
|
CardDescriptor * cd = NULL;
|
||||||
|
//max targets allowed
|
||||||
|
size_t limit = s1.find('<');
|
||||||
|
if (limit != string::npos)
|
||||||
|
{
|
||||||
|
size_t end = s1.find(">", limit);
|
||||||
|
string howmany;
|
||||||
|
if (end != string::npos)
|
||||||
|
{
|
||||||
|
howmany = s1.substr(limit + 1, end - limit - 1);
|
||||||
|
WParsedInt * howmuch = NEW WParsedInt(howmany, NULL, card);
|
||||||
|
maxtargets = howmuch->getValue();
|
||||||
|
delete howmuch;
|
||||||
|
s1 = s1.substr(end + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (s1.size())
|
while (s1.size())
|
||||||
{
|
{
|
||||||
found = s1.find(",");
|
found = s1.find(",");
|
||||||
string typeName;
|
string typeName;
|
||||||
@@ -206,8 +222,11 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta
|
|||||||
size_t operatorPosition = attribute.find("=", 1);
|
size_t operatorPosition = attribute.find("=", 1);
|
||||||
if (operatorPosition != string::npos)
|
if (operatorPosition != string::npos)
|
||||||
{
|
{
|
||||||
comparisonCriterion = atoi(
|
string numberCD = attribute.substr(operatorPosition + 1, attribute.size() - operatorPosition - 1);
|
||||||
attribute.substr(operatorPosition + 1, attribute.size() - operatorPosition - 1).c_str());
|
WParsedInt * val = NEW WParsedInt(numberCD,NULL, card);
|
||||||
|
comparisonCriterion = val->getValue();
|
||||||
|
/*atoi(attribute.substr(operatorPosition + 1, attribute.size() - operatorPosition - 1).c_str());*/
|
||||||
|
delete val;
|
||||||
switch (attribute[operatorPosition - 1])
|
switch (attribute[operatorPosition - 1])
|
||||||
{
|
{
|
||||||
case '<':
|
case '<':
|
||||||
@@ -305,10 +324,112 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta
|
|||||||
{
|
{
|
||||||
cd->unsecuresetfresh(1);
|
cd->unsecuresetfresh(1);
|
||||||
}
|
}
|
||||||
//Power restrictions
|
}
|
||||||
|
//creature is a level up creature
|
||||||
|
else if (attribute.find("leveler") != string::npos)
|
||||||
|
{
|
||||||
|
if (minus)
|
||||||
|
{
|
||||||
|
cd->isLeveler = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cd->isLeveler = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//creature is a level up creature
|
||||||
|
else if (attribute.find("enchanted") != string::npos)
|
||||||
|
{
|
||||||
|
if (minus)
|
||||||
|
{
|
||||||
|
cd->CDenchanted = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cd->CDenchanted = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (attribute.find("multicolor") != string::npos)
|
||||||
|
{
|
||||||
|
//card is multicolored?
|
||||||
|
if (minus)
|
||||||
|
{
|
||||||
|
cd->setisMultiColored(-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cd->setisMultiColored(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (attribute.find("blackandgreen") != string::npos)
|
||||||
|
{
|
||||||
|
//card is both colors?
|
||||||
|
if (minus)
|
||||||
|
{
|
||||||
|
cd->setisBlackAndGreen(-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cd->setisBlackAndGreen(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (attribute.find("blackandwhite") != string::npos)
|
||||||
|
{
|
||||||
|
//card is both colors?
|
||||||
|
if (minus)
|
||||||
|
{
|
||||||
|
cd->setisBlackAndWhite(-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cd->setisBlackAndWhite(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (attribute.find("redandblue") != string::npos)
|
||||||
|
{
|
||||||
|
//card is both colors?
|
||||||
|
if (minus)
|
||||||
|
{
|
||||||
|
cd->setisRedAndBlue(-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cd->setisRedAndBlue(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (attribute.find("blueandgreen") != string::npos)
|
||||||
|
{
|
||||||
|
//card is both colors?
|
||||||
|
if (minus)
|
||||||
|
{
|
||||||
|
cd->setisBlueAndGreen(-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cd->setisBlueAndGreen(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (attribute.find("redandwhite") != string::npos)
|
||||||
|
{
|
||||||
|
//card is both colors?
|
||||||
|
if (minus)
|
||||||
|
{
|
||||||
|
cd->setisRedAndWhite(-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cd->setisRedAndWhite(1);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (attribute.find("power") != string::npos)
|
else if (attribute.find("power") != string::npos)
|
||||||
{
|
{
|
||||||
|
//Power restrictions
|
||||||
cd->setPower(comparisonCriterion);
|
cd->setPower(comparisonCriterion);
|
||||||
cd->powerComparisonMode = comparisonMode;
|
cd->powerComparisonMode = comparisonMode;
|
||||||
//Toughness restrictions
|
//Toughness restrictions
|
||||||
@@ -462,6 +583,8 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta
|
|||||||
|
|
||||||
TargetChooser * TargetChooserFactory::createTargetChooser(MTGCardInstance * card)
|
TargetChooser * TargetChooserFactory::createTargetChooser(MTGCardInstance * card)
|
||||||
{
|
{
|
||||||
|
if(!card)
|
||||||
|
return NULL;
|
||||||
int id = card->getId();
|
int id = card->getId();
|
||||||
string s = card->spellTargetType;
|
string s = card->spellTargetType;
|
||||||
if (card->alias)
|
if (card->alias)
|
||||||
@@ -540,6 +663,11 @@ bool TargetChooser::canTarget(Targetable * target)
|
|||||||
tempcard = tempcard->previous;
|
tempcard = tempcard->previous;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(source && ((source->hasSubtype("aura") || source->hasSubtype("equipment")) && source->target && source->target == card && source->target->isPhased && targetter->target == card))
|
||||||
|
return true;
|
||||||
|
//this is kinda cheating but by defualt we let auras and equipments always contenue to target a phased creature.
|
||||||
|
else if(card->isPhased)
|
||||||
|
return false;
|
||||||
if (source && targetter && card->isInPlay())
|
if (source && targetter && card->isInPlay())
|
||||||
{
|
{
|
||||||
if (card->has(Constants::SHROUD)) return false;
|
if (card->has(Constants::SHROUD)) return false;
|
||||||
@@ -574,7 +702,7 @@ int TargetChooser::ForceTargetListReady()
|
|||||||
|
|
||||||
int TargetChooser::targetsReadyCheck()
|
int TargetChooser::targetsReadyCheck()
|
||||||
{
|
{
|
||||||
if (cursor == 0)
|
if (cursor <= 0)
|
||||||
{
|
{
|
||||||
return TARGET_NOK;
|
return TARGET_NOK;
|
||||||
}
|
}
|
||||||
@@ -605,8 +733,8 @@ bool TargetChooser::validTargetsExist()
|
|||||||
{
|
{
|
||||||
Player *p = GameObserver::GetInstance()->players[i];
|
Player *p = GameObserver::GetInstance()->players[i];
|
||||||
if (canTarget(p)) return true;
|
if (canTarget(p)) return true;
|
||||||
MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library };
|
MTGGameZone * zones[] = { p->game->inPlay, p->game->graveyard, p->game->hand, p->game->library, p->game->exile };
|
||||||
for (int k = 0; k < 4; k++)
|
for (int k = 0; k < 5; k++)
|
||||||
{
|
{
|
||||||
MTGGameZone * z = zones[k];
|
MTGGameZone * z = zones[k];
|
||||||
if (targetsZone(z))
|
if (targetsZone(z))
|
||||||
@@ -764,7 +892,8 @@ bool DescriptorTargetChooser::canTarget(Targetable * target)
|
|||||||
if (target->typeAsTarget() == TARGET_CARD)
|
if (target->typeAsTarget() == TARGET_CARD)
|
||||||
{
|
{
|
||||||
MTGCardInstance * _target = (MTGCardInstance *) target;
|
MTGCardInstance * _target = (MTGCardInstance *) target;
|
||||||
if (cd->match(_target)) return true;
|
if (cd->match(_target))
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else if (target->typeAsTarget() == TARGET_STACKACTION)
|
else if (target->typeAsTarget() == TARGET_STACKACTION)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -135,13 +135,44 @@ int TestSuiteAI::Act(float dt)
|
|||||||
playMode = MODE_AI;
|
playMode = MODE_AI;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if (action.compare("next") == 0)
|
else if (action.compare("next") == 0 || action.find("goto") != string::npos)
|
||||||
{
|
{
|
||||||
GuiCombat * gc = g->mLayers->combatLayer();
|
if(action.find("goto ")!= string::npos)
|
||||||
if (ORDER == g->combatStep || DAMAGE == g->combatStep)
|
{
|
||||||
gc->clickOK();
|
size_t found = action.find("goto ");
|
||||||
|
string phase = action.substr(found + 5);
|
||||||
|
int phaseToGo = 0;
|
||||||
|
for (int i = 0; i < Constants::NB_MTG_PHASES; i++)
|
||||||
|
{
|
||||||
|
if (phase.find(Constants::MTGPhaseCodeNames[i]) != string::npos)
|
||||||
|
{
|
||||||
|
phaseToGo = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(g->currentGamePhase != phaseToGo)
|
||||||
|
suite->currentAction--;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
GuiCombat * gc = g->mLayers->combatLayer();
|
||||||
|
if (ORDER == g->combatStep || DAMAGE == g->combatStep)
|
||||||
|
{
|
||||||
|
gc->clickOK();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g->userRequestNextGamePhase();
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
g->userRequestNextGamePhase();
|
{
|
||||||
|
GuiCombat * gc = g->mLayers->combatLayer();
|
||||||
|
if (ORDER == g->combatStep || DAMAGE == g->combatStep)
|
||||||
|
gc->clickOK();
|
||||||
|
else
|
||||||
|
g->userRequestNextGamePhase();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (action.compare("yes") == 0)
|
else if (action.compare("yes") == 0)
|
||||||
g->mLayers->stackLayer()->setIsInterrupting(this);
|
g->mLayers->stackLayer()->setIsInterrupting(this);
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ ThisDescriptor * ThisDescriptorFactory::createThisDescriptor(string s)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//equips
|
//equips and auras
|
||||||
found = s.find("gear");//still same meaning, better wording to word conflict with MTGAbility equip.
|
found = s.find("gear");//still same meaning, better wording to word conflict with MTGAbility equip.
|
||||||
if (found != string::npos)
|
if (found != string::npos)
|
||||||
{
|
{
|
||||||
@@ -156,7 +156,52 @@ ThisDescriptor * ThisDescriptorFactory::createThisDescriptor(string s)
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
found = s.find("auras");
|
||||||
|
if (found != string::npos)
|
||||||
|
{
|
||||||
|
ThisAuras * td = NEW ThisAuras(criterion);
|
||||||
|
if (td)
|
||||||
|
{
|
||||||
|
td->comparisonMode = mode;
|
||||||
|
return td;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// opponent damage count
|
||||||
|
found = s.find("opponentdamagecount");
|
||||||
|
if (found != string::npos)
|
||||||
|
{
|
||||||
|
ThisOpponentDamageAmount * td = NEW ThisOpponentDamageAmount(criterion);
|
||||||
|
if (td)
|
||||||
|
{
|
||||||
|
td->comparisonMode = mode;
|
||||||
|
return td;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
//untapped status
|
||||||
|
found = s.find("untapped");
|
||||||
|
if (found != string::npos)
|
||||||
|
{
|
||||||
|
ThisUntapped * td = NEW ThisUntapped(criterion);
|
||||||
|
if (td)
|
||||||
|
{
|
||||||
|
td->comparisonMode = mode;
|
||||||
|
return td;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
found = s.find("tapped");
|
||||||
|
if (found != string::npos)
|
||||||
|
{
|
||||||
|
ThisTapped * td = NEW ThisTapped(criterion);
|
||||||
|
if (td)
|
||||||
|
{
|
||||||
|
td->comparisonMode = mode;
|
||||||
|
return td;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
//whenever this creature attacks do effect
|
//whenever this creature attacks do effect
|
||||||
found = s.find("attacking");
|
found = s.find("attacking");
|
||||||
if (found != string::npos)
|
if (found != string::npos)
|
||||||
@@ -338,6 +383,42 @@ int ThisEquip::match(MTGCardInstance * card)
|
|||||||
return matchValue(card->equipment);
|
return matchValue(card->equipment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ThisAuras::ThisAuras(int auras)
|
||||||
|
{
|
||||||
|
comparisonCriterion = auras;
|
||||||
|
}
|
||||||
|
int ThisAuras::match(MTGCardInstance * card)
|
||||||
|
{
|
||||||
|
return matchValue(card->auras);
|
||||||
|
}
|
||||||
|
|
||||||
|
ThisOpponentDamageAmount::ThisOpponentDamageAmount(int damagecount)
|
||||||
|
{
|
||||||
|
comparisonCriterion = damagecount;
|
||||||
|
}
|
||||||
|
int ThisOpponentDamageAmount::match(MTGCardInstance * card)
|
||||||
|
{
|
||||||
|
return matchValue(card->controller()->opponent()->damageCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
ThisUntapped::ThisUntapped(int untapped)
|
||||||
|
{
|
||||||
|
comparisonCriterion = untapped;
|
||||||
|
}
|
||||||
|
int ThisUntapped::match(MTGCardInstance * card)
|
||||||
|
{
|
||||||
|
return matchValue(!card->isTapped());
|
||||||
|
}
|
||||||
|
|
||||||
|
ThisTapped::ThisTapped(int tapped)
|
||||||
|
{
|
||||||
|
comparisonCriterion = tapped;
|
||||||
|
}
|
||||||
|
int ThisTapped::match(MTGCardInstance * card)
|
||||||
|
{
|
||||||
|
return matchValue(card->isTapped());
|
||||||
|
}
|
||||||
|
|
||||||
ThisAttacked::ThisAttacked(int attack)
|
ThisAttacked::ThisAttacked(int attack)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ Token::Token(string _name, MTGCardInstance * source, int _power, int _toughness)
|
|||||||
toughness = _toughness;
|
toughness = _toughness;
|
||||||
life = toughness;
|
life = toughness;
|
||||||
lifeOrig = life;
|
lifeOrig = life;
|
||||||
|
origpower = _power;
|
||||||
|
origtoughness = _toughness;
|
||||||
rarity = Constants::RARITY_T;
|
rarity = Constants::RARITY_T;
|
||||||
name = _name;
|
name = _name;
|
||||||
if (name.size() && name[0] >= 97 && name[0] <= 122) name[0] -= 32; //Poor man's camelcase. We assume strings we get are either Camelcased or lowercase
|
if (name.size() && name[0] >= 97 && name[0] <= 122) name[0] -= 32; //Poor man's camelcase. We assume strings we get are either Camelcased or lowercase
|
||||||
|
|||||||
@@ -103,7 +103,11 @@ bool WCachedTexture::isLocked()
|
|||||||
|
|
||||||
for (vector<WTrackedQuad*>::iterator it = trackedQuads.begin(); it != trackedQuads.end(); it++)
|
for (vector<WTrackedQuad*>::iterator it = trackedQuads.begin(); it != trackedQuads.end(); it++)
|
||||||
{
|
{
|
||||||
if ((*it)->isLocked()) return true;
|
if ((*it) && (*it)->isLocked()) return true;
|
||||||
|
//null case
|
||||||
|
//tokens that were using workarounds such as mixes of aslongas with CD checks
|
||||||
|
//and thisforeach would call to cache the tokens image, but since the effect never resolved it was NULL
|
||||||
|
//when it came time to check if it was locked, it would trigger a break point here.
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -21,6 +21,11 @@ WEventDamage::WEventDamage(Damage *damage) :
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WEventLife::WEventLife(Player * player,int amount,int Ltype) :
|
||||||
|
WEvent(), player(player),amount(amount), Ltype(Ltype)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
WEventDamageStackResolved::WEventDamageStackResolved() :
|
WEventDamageStackResolved::WEventDamageStackResolved() :
|
||||||
WEvent()
|
WEvent()
|
||||||
{
|
{
|
||||||
@@ -87,6 +92,16 @@ WEventCardDiscard::WEventCardDiscard(MTGCardInstance * card) :
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WEventVampire::WEventVampire(MTGCardInstance * card,MTGCardInstance * source,MTGCardInstance * victem) :
|
||||||
|
WEventCardUpdate(card),source(source),victem(victem)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
WEventTarget::WEventTarget(MTGCardInstance * card,MTGCardInstance * source) :
|
||||||
|
WEventCardUpdate(card),card(card),source(source)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
WEventCardChangeType::WEventCardChangeType(MTGCardInstance * card, int type, bool before, bool after) :
|
WEventCardChangeType::WEventCardChangeType(MTGCardInstance * card, int type, bool before, bool after) :
|
||||||
WEventCardUpdate(card), type(type), before(before), after(after)
|
WEventCardUpdate(card), type(type), before(before), after(after)
|
||||||
{
|
{
|
||||||
@@ -144,6 +159,42 @@ int WEventDamage::getValue()
|
|||||||
return damage->damage;
|
return damage->damage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Targetable * WEventLife::getTarget(int target)
|
||||||
|
{
|
||||||
|
switch (target)
|
||||||
|
{
|
||||||
|
case TARGET_TO:
|
||||||
|
return player;
|
||||||
|
case TARGET_FROM:
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Targetable * WEventVampire::getTarget(int target)
|
||||||
|
{
|
||||||
|
switch (target)
|
||||||
|
{
|
||||||
|
case TARGET_TO:
|
||||||
|
return victem->next;
|
||||||
|
case TARGET_FROM:
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Targetable * WEventTarget::getTarget(int target)
|
||||||
|
{
|
||||||
|
switch (target)
|
||||||
|
{
|
||||||
|
case TARGET_TO:
|
||||||
|
return card;
|
||||||
|
case TARGET_FROM:
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
Targetable * WEventZoneChange::getTarget(int target)
|
Targetable * WEventZoneChange::getTarget(int target)
|
||||||
{
|
{
|
||||||
if (target) return card;
|
if (target) return card;
|
||||||
|
|||||||
Reference in New Issue
Block a user