first part of a series of commits, this one adds "and((" support to the various card removel abilities, tweaks targetedplayer targetchooser, and adds the following number word variables...
counter{}
so you can get a count of a certain counter on a card
the next consist of parts using the same targetchooser method as type:
power:
toughness:
convertedcost:
followed by ---
highest:
lowest:
followed by targetchooser
blah:mybattlefield
so if i want highest converted cost of creatures i control..
convertedcost:highest:creature:mybattlefield
also added an internal ability to reuse and display flying text with a string passed to it.
This commit is contained in:
@@ -26,6 +26,17 @@ using std::map;
|
||||
//
|
||||
// Misc classes
|
||||
//
|
||||
class MTGEventText: public MTGAbility
|
||||
{
|
||||
public:
|
||||
int textAlpha;
|
||||
string text;
|
||||
void Update(float dt);
|
||||
void Render();
|
||||
MTGEventText(GameObserver* observer, int _id,MTGCardInstance * card, string text);
|
||||
virtual MTGEventText * clone() const;
|
||||
};
|
||||
|
||||
class WParsedInt
|
||||
{
|
||||
public:
|
||||
@@ -41,6 +52,8 @@ public:
|
||||
private:
|
||||
void init(string s, Spell * spell, MTGCardInstance * card)
|
||||
{
|
||||
if(!s.size())
|
||||
return;
|
||||
if(!card)
|
||||
return;
|
||||
MTGCardInstance * target = card->target;
|
||||
@@ -91,6 +104,10 @@ private:
|
||||
if(intValue < 0)
|
||||
intValue = 0;
|
||||
}
|
||||
else if (s == "castx")
|
||||
{
|
||||
intValue = card->castX;
|
||||
}
|
||||
else if (s == "gear")
|
||||
{
|
||||
intValue = target->equipment;
|
||||
@@ -135,6 +152,97 @@ private:
|
||||
}
|
||||
SAFE_DELETE(tc);
|
||||
}
|
||||
else if (s.find("counter{") != string::npos)
|
||||
{
|
||||
intValue = 0;
|
||||
vector<string>counterName = parseBetween(s,"counter{","}");
|
||||
if(counterName.size())
|
||||
{
|
||||
AbilityFactory abf(target->getObserver());
|
||||
Counter * counter = abf.parseCounter(counterName[1], NULL);
|
||||
if(counter && target->counters && target->counters->hasCounter(counter->name.c_str(),counter->power,counter->toughness))
|
||||
{
|
||||
Counter * targetCounter = target->counters->hasCounter(counter->name.c_str(), counter->power, counter->toughness);
|
||||
intValue = targetCounter->nb;
|
||||
}
|
||||
SAFE_DELETE(counter);
|
||||
}
|
||||
}
|
||||
else if (s.find("convertedcost:") != string::npos || s.find("power:") != string::npos || s.find("toughness:") != string::npos)
|
||||
{
|
||||
bool powerCheck = false;
|
||||
bool toughnessCheck = false;
|
||||
bool costCheck = false;
|
||||
intValue = 0;
|
||||
vector<string>convertedType = parseBetween(s,"convertedcost:",":");
|
||||
if(convertedType.size())
|
||||
costCheck = true;
|
||||
else
|
||||
{
|
||||
convertedType = parseBetween(s,"power:",":");
|
||||
if(convertedType.size())
|
||||
powerCheck = true;
|
||||
else
|
||||
{
|
||||
convertedType = parseBetween(s,"toughness:",":");
|
||||
if(convertedType.size())
|
||||
toughnessCheck = true;
|
||||
}
|
||||
}
|
||||
if(!convertedType.size())
|
||||
return;
|
||||
bool high = false;
|
||||
int highest = 0;
|
||||
int lowest = 5000;
|
||||
if(convertedType[1].find("highest") != string::npos)
|
||||
high = true;
|
||||
|
||||
string theType = convertedType[2];
|
||||
size_t zoned = theType.find(":");
|
||||
if(zoned == string::npos)
|
||||
{
|
||||
theType.append("|mybattlefield");
|
||||
}
|
||||
else
|
||||
{
|
||||
replace(theType.begin(), theType.end(), ':', '|');
|
||||
}
|
||||
TargetChooserFactory tf(card->getObserver());
|
||||
TargetChooser * tc = tf.createTargetChooser(theType.c_str(),NULL);
|
||||
int check = 0;
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
Player * p = card->getObserver()->players[i];
|
||||
MTGGameZone * zones[] = { p->game->battlefield, p->game->graveyard, p->game->hand, p->game->library };
|
||||
for (int k = 0; k < 4; k++)
|
||||
{
|
||||
MTGGameZone * zone = zones[k];
|
||||
if(tc->targetsZone(zone,target))
|
||||
{
|
||||
for(unsigned int w = 0;w < zone->cards.size();++w)
|
||||
{
|
||||
MTGCardInstance * cCard = zone->cards[w];
|
||||
if(tc->canTarget(cCard))
|
||||
{
|
||||
if(costCheck)
|
||||
check = cCard->getManaCost()->getConvertedCost();
|
||||
if(powerCheck)
|
||||
check = cCard->power;
|
||||
if(toughnessCheck)
|
||||
check = cCard->toughness;
|
||||
|
||||
check > highest?highest = check:highest = highest;
|
||||
check <= lowest?lowest = check:lowest = lowest;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(lowest == 5000)
|
||||
lowest = 0;
|
||||
SAFE_DELETE(tc);
|
||||
intValue = high?highest:lowest;
|
||||
}
|
||||
else if (s == "sunburst")
|
||||
{
|
||||
intValue = 0;
|
||||
@@ -147,6 +255,14 @@ private:
|
||||
{
|
||||
intValue = target->controller()->life;
|
||||
}
|
||||
else if (s == "highestlifetotal")
|
||||
{
|
||||
intValue = target->controller()->life <= target->controller()->opponent()->life? target->controller()->opponent()->life:target->controller()->life;
|
||||
}
|
||||
else if (s == "lowestlifetotal")
|
||||
{
|
||||
intValue = target->controller()->life <= target->controller()->opponent()->life? target->controller()->life:target->controller()->opponent()->life;
|
||||
}
|
||||
else if (s == "thatmuch")
|
||||
{
|
||||
//the value that much is a variable to be used with triggered abilities.
|
||||
@@ -884,7 +1000,7 @@ public:
|
||||
};
|
||||
|
||||
//if/ifnot Cond then EFFECT
|
||||
class IfThenAbility: public ActivatedAbility
|
||||
class IfThenAbility: public InstantAbility
|
||||
{
|
||||
public:
|
||||
MTGAbility * delayedAbility;
|
||||
@@ -1067,37 +1183,45 @@ public:
|
||||
class AABuryCard: public ActivatedAbility
|
||||
{
|
||||
public:
|
||||
MTGAbility * andAbility;
|
||||
AABuryCard(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target);
|
||||
int resolve();
|
||||
const char * getMenuText();
|
||||
AABuryCard * clone() const;
|
||||
~AABuryCard();
|
||||
};
|
||||
|
||||
class AADestroyCard: public ActivatedAbility
|
||||
{
|
||||
public:
|
||||
MTGAbility * andAbility;
|
||||
AADestroyCard(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target);
|
||||
int resolve();
|
||||
const char * getMenuText();
|
||||
AADestroyCard * clone() const;
|
||||
~AADestroyCard();
|
||||
};
|
||||
|
||||
class AASacrificeCard: public ActivatedAbility
|
||||
{
|
||||
public:
|
||||
MTGAbility * andAbility;
|
||||
AASacrificeCard(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target);
|
||||
int resolve();
|
||||
const char * getMenuText();
|
||||
AASacrificeCard * clone() const;
|
||||
~AASacrificeCard();
|
||||
};
|
||||
|
||||
class AADiscardCard: public ActivatedAbility
|
||||
{
|
||||
public:
|
||||
MTGAbility * andAbility;
|
||||
AADiscardCard(GameObserver* observer, int _id, MTGCardInstance * _source, MTGCardInstance * _target);
|
||||
int resolve();
|
||||
const char * getMenuText();
|
||||
AADiscardCard * clone() const;
|
||||
~AADiscardCard();
|
||||
};
|
||||
|
||||
/* Generic Target Ability */
|
||||
@@ -1110,8 +1234,9 @@ public:
|
||||
int counters;
|
||||
MTGGameZone * activeZone;
|
||||
string newName;
|
||||
string tcString;
|
||||
|
||||
GenericTargetAbility(GameObserver* observer, string newName, string castRestriction, int _id, MTGCardInstance * _source, TargetChooser * _tc, MTGAbility * a, ManaCost * _cost = NULL, string limit = "",MTGAbility * sideEffects = NULL,string usesBeforeSideEffects = "", int restrictions = 0, MTGGameZone * dest = NULL);
|
||||
GenericTargetAbility(GameObserver* observer, string newName, string castRestriction, int _id, MTGCardInstance * _source, TargetChooser * _tc, MTGAbility * a, ManaCost * _cost = NULL, string limit = "",MTGAbility * sideEffects = NULL,string usesBeforeSideEffects = "", int restrictions = 0, MTGGameZone * dest = NULL,string tcString ="");
|
||||
const char * getMenuText();
|
||||
~GenericTargetAbility();
|
||||
GenericTargetAbility * clone() const;
|
||||
@@ -1775,6 +1900,49 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
//this generic ability assumes that what is added will take care of its own removel.
|
||||
class GenericAbilityMod: public InstantAbility, public NestedAbility
|
||||
{
|
||||
public:
|
||||
GenericAbilityMod(GameObserver* observer, int _id, MTGCardInstance * _source, Damageable * _target, MTGAbility * ability) :
|
||||
InstantAbility(observer, _id, _source,_target), NestedAbility(ability)
|
||||
{
|
||||
ability->target = _target;
|
||||
}
|
||||
|
||||
int addToGame()
|
||||
{
|
||||
InstantAbility::addToGame();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int resolve()
|
||||
{
|
||||
MTGAbility * toAdd = ability->clone();
|
||||
toAdd->forceDestroy = -1;
|
||||
toAdd->target = target;
|
||||
toAdd->addToGame();
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char * getMenuText()
|
||||
{
|
||||
return ability->getMenuText();
|
||||
}
|
||||
|
||||
GenericAbilityMod * clone() const
|
||||
{
|
||||
GenericAbilityMod * a = NEW GenericAbilityMod(*this);
|
||||
a->ability = ability->clone();
|
||||
return a;
|
||||
}
|
||||
|
||||
~GenericAbilityMod()
|
||||
{
|
||||
SAFE_DELETE(ability);
|
||||
}
|
||||
};
|
||||
|
||||
//Circle of Protections
|
||||
class ACircleOfProtection: public TargetAbility
|
||||
{
|
||||
@@ -2987,6 +3155,7 @@ class AADamager: public ActivatedAbilityTP
|
||||
{
|
||||
public:
|
||||
string d;
|
||||
bool redirected;
|
||||
|
||||
AADamager(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable * _target, string d, ManaCost * _cost = NULL,
|
||||
int who = TargetChooser::UNSET);
|
||||
@@ -5035,7 +5204,7 @@ public:
|
||||
target = copy;
|
||||
source->target = copy;
|
||||
copy->summoningSickness = 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ public:
|
||||
MTGGameZone * currentZone;
|
||||
Pos* view;
|
||||
int X;
|
||||
int castX;
|
||||
int alternateCostPaid[ManaCost::MANA_PAID_WITH_RETRACE + 1];
|
||||
int paymenttype;
|
||||
int castMethod; /* Tells if the card reached its current zone by being cast or not (brought into the zone by an effect). non 0 == cast, 0 == not cast */
|
||||
@@ -118,6 +119,7 @@ public:
|
||||
Counters * counters;
|
||||
const string getDisplayName() const;
|
||||
MTGCardInstance * target;
|
||||
Player * playerTarget;
|
||||
vector<Targetable *> backupTargets;
|
||||
|
||||
|
||||
|
||||
@@ -32,6 +32,14 @@ public:
|
||||
Spell * getNextSpellTarget(Spell * previous = 0);
|
||||
Damage * getNextDamageTarget(Damage * previous = 0);
|
||||
Targetable * getNextTarget(Targetable * previous = 0);
|
||||
vector<Targetable*> getTargetsFrom()
|
||||
{
|
||||
return targets;
|
||||
}
|
||||
void setTargetsTo(vector<Targetable*>targetTo)
|
||||
{
|
||||
targets = targetTo;
|
||||
}
|
||||
void initTargets()
|
||||
{
|
||||
targets.clear();
|
||||
|
||||
Reference in New Issue
Block a user