added basic card draw replacement,

auto=replacedraw choice damage:2

auto=replacedraw choice draw:2 noreplace

notice noreplace exempts the draw from sending a draw event. draw events and drawn events are seperate events.

added dredge and it's rules.

[card]
name=Dakmor Salvage
auto=tap
auto={t}:add{b}
dredge=dredge(2)
text=Dakmor Salvage enters the battlefield tapped. -- {T}: Add {B} to your mana pool. -- Dredge 2 (If you would draw a card, instead you may put exactly two cards from the top of your library into your graveyard. If you do, return this card from your graveyard to your hand. Otherwise, draw a card.)
type=Land
[/card]
This commit is contained in:
omegablast2002@yahoo.com
2013-01-20 20:13:07 +00:00
parent 0709aaefb8
commit ca3dc49d71
20 changed files with 463 additions and 31 deletions
+1 -1
View File
@@ -44,7 +44,7 @@ public:
int reactToTargetClick(ActionElement * ability, Targetable * card); int reactToTargetClick(ActionElement * ability, Targetable * card);
int stillInUse(MTGCardInstance * card); int stillInUse(MTGCardInstance * card);
void setMenuObject(Targetable * object, bool must = false); void setMenuObject(Targetable * object, bool must = false);
void setCustomMenuObject(Targetable * object, bool must = false,vector<MTGAbility*>abilities = vector<MTGAbility*>()); void setCustomMenuObject(Targetable * object, bool must = false,vector<MTGAbility*>abilities = vector<MTGAbility*>(),string customName = "");
void ButtonPressed(int controllerid, int controlid); void ButtonPressed(int controllerid, int controlid);
void ButtonPressedOnMultipleChoice(int choice = -1); void ButtonPressedOnMultipleChoice(int choice = -1);
void doReactTo(int menuIndex); void doReactTo(int menuIndex);
+24 -4
View File
@@ -1105,7 +1105,8 @@ public:
MTGAbility * mClone; MTGAbility * mClone;
vector<MTGAbility*>abilities; vector<MTGAbility*>abilities;
Player * who; Player * who;
MenuAbility(GameObserver* observer, int _id, Targetable * target, MTGCardInstance * _source, bool must = false, vector<MTGAbility*>abilities = vector<MTGAbility*>(),Player * who = NULL); string newNameString;
MenuAbility(GameObserver* observer, int _id, Targetable * target, MTGCardInstance * _source, bool must = false, vector<MTGAbility*>abilities = vector<MTGAbility*>(),Player * who = NULL,string _newName = "");
void Update(float dt); void Update(float dt);
int resolve(); int resolve();
const char * getMenuText(); const char * getMenuText();
@@ -1393,9 +1394,9 @@ class AADrawer: public ActivatedAbilityTP
public: public:
string nbcardsStr; string nbcardsStr;
bool noReplace;
AADrawer(GameObserver* observer, int _id, MTGCardInstance * card, Targetable * _target, ManaCost * _cost,string nbcardsStr, int who = AADrawer(GameObserver* observer, int _id, MTGCardInstance * card, Targetable * _target, ManaCost * _cost,string nbcardsStr, int who =
TargetChooser::UNSET); TargetChooser::UNSET,bool noReplace = false);
int resolve(); int resolve();
const char * getMenuText(); const char * getMenuText();
AADrawer * clone() const; AADrawer * clone() const;
@@ -2622,7 +2623,14 @@ public:
int resolve(); int resolve();
PairCard * clone() const; PairCard * clone() const;
}; };
//pick a card to dredge
class dredgeCard: public InstantAbility
{
public:
dredgeCard(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, ManaCost * _cost = NULL);
int resolve();
dredgeCard * clone() const;
};
/* create a parent child association between cards */ /* create a parent child association between cards */
class AAConnect: public InstantAbility class AAConnect: public InstantAbility
{ {
@@ -4300,6 +4308,18 @@ public:
}; };
class ADrawReplacer: public MTGAbility
{
public:
REDrawReplacement * re;
MTGAbility * replacer;
bool OtherPlayer;
ADrawReplacer(GameObserver* observer, int id, MTGCardInstance * source, MTGAbility * _replace = NULL,bool otherPlayer = false);
int addToGame();
int destroy();
ADrawReplacer * clone() const;
~ADrawReplacer();
};
/* /*
Specific Classes Specific Classes
*/ */
+2 -1
View File
@@ -66,6 +66,7 @@ public:
int power; int power;
int toughness; int toughness;
int suspendedTime; int suspendedTime;
int dredgeAmount;
vector<int>types; vector<int>types;
CardPrimitive(); CardPrimitive();
@@ -110,7 +111,7 @@ public:
bool isCreature(); bool isCreature();
bool isLand(); bool isLand();
bool isSpell(); bool isSpell();
int dredge();
void setPower(int _power); void setPower(int _power);
int getPower(); int getPower();
void setToughness(int _toughness); void setToughness(int _toughness);
+1
View File
@@ -99,6 +99,7 @@ public:
int fresh; int fresh;
int MaxLevelUp; int MaxLevelUp;
int kicked; int kicked;
int dredge;
bool isDualWielding; bool isDualWielding;
bool stillNeeded; bool stillNeeded;
Player * lastController; Player * lastController;
+18
View File
@@ -272,6 +272,24 @@ public:
virtual ostream& toString(ostream& out) const; virtual ostream& toString(ostream& out) const;
virtual MTGSoulbondRule * clone() const; virtual MTGSoulbondRule * clone() const;
}; };
/*dredge*/
class MTGDredgeRule: public PermanentAbility, public ReplacementEffect
{
public:
vector<MTGCardInstance*>soulbonders;
TargetChooser * tcb;
MTGAbility * dredgeAbility;
MTGAbility * targetAbility;
MTGAbility * targetAbilityAdder;
MTGAbility * targetAbility1;
MTGAbility * mod;
MTGAbility * activateDredge;
vector<MTGAbility*>pairing;
MTGDredgeRule(GameObserver* observer, int _id);
WEvent * replace(WEvent *e);
virtual ostream& toString(ostream& out) const;
virtual MTGDredgeRule * clone() const;
};
/* Persist Rule */ /* Persist Rule */
class MTGPersistRule: public PermanentAbility class MTGPersistRule: public PermanentAbility
{ {
+13 -3
View File
@@ -49,12 +49,22 @@ public:
WEvent * replace(WEvent *e); WEvent * replace(WEvent *e);
~RECountersPrevention(); ~RECountersPrevention();
}; };
class REDrawReplacement: public ReplacementEffect
class ReplacementEffects
{ {
protected: protected:
list<ReplacementEffect *> modifiers; MTGAbility * source;
public: public:
Player * DrawerOfCard;
MTGAbility * replacementAbility;
REDrawReplacement(MTGAbility * _source, Player * Drawer = NULL, MTGAbility * replaceWith = NULL);
WEvent * replace(WEvent *e);
~REDrawReplacement();
};
class ReplacementEffects
{
public:
list<ReplacementEffect *> modifiers;
ReplacementEffects(); ReplacementEffects();
WEvent * replace(WEvent *e); WEvent * replace(WEvent *e);
int add(ReplacementEffect * re); int add(ReplacementEffect * re);
+19
View File
@@ -298,6 +298,25 @@ public:
virtual bool equals(TargetChooser * tc); virtual bool equals(TargetChooser * tc);
}; };
class dredgeChooser: public TypeTargetChooser
{
public:
bool withoutProtections;
dredgeChooser(GameObserver *observer, int * _zones, int _nbzones, MTGCardInstance * card = NULL, int _maxtargets = 1, bool other = false, bool targetMin = false) :
TypeTargetChooser(observer, "*|mygraveyard",_zones, _nbzones, card, _maxtargets, other, targetMin)
{
}
;
dredgeChooser(GameObserver *observer, MTGCardInstance * card = NULL, int _maxtargets = 1, bool other = false,bool targetMin = false) :
TypeTargetChooser(observer, "*|mygraveyard", card, _maxtargets, other,targetMin)
{
}
;
virtual bool canTarget(Targetable * target, bool withoutProtections = false);
virtual dredgeChooser * clone() const;
virtual bool equals(TargetChooser * tc);
};
class myCursesChooser: public TypeTargetChooser class myCursesChooser: public TypeTargetChooser
{ {
public: public:
+9 -1
View File
@@ -12,6 +12,8 @@ class Targetable;
class ManaPool; class ManaPool;
class AACounter; class AACounter;
class Counters; class Counters;
class MTGAbility;
class DrawAction;
class WEvent { class WEvent {
public: public:
@@ -221,7 +223,13 @@ struct WEventcardDraw : public WEvent {
int nb_cards; int nb_cards;
virtual Targetable * getTarget(Player * player); virtual Targetable * getTarget(Player * player);
}; };
//event for a card draw ability resolving
struct WEventDraw : public WEvent {
WEventDraw(Player * player,int nb_cards,MTGAbility * drawer);
Player * player;
int nb_cards;
MTGAbility * drawAbility;
};
//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.
+1 -1
View File
@@ -602,7 +602,7 @@ int OrderedAIAction::getEfficiency()
if (!efficiency && may) if (!efficiency && may)
{ {
AIPlayer * chk = (AIPlayer*)p; AIPlayer * chk = (AIPlayer*)p;
if(may->ability->getActionTc() && chk->chooseTarget(may->ability->getActionTc(),NULL,NULL,true)) if(may->ability && may->ability->getActionTc() && chk->chooseTarget(may->ability->getActionTc(),NULL,NULL,true))
efficiency = 50 + (owner->getRandomGenerator()->random() % 50); efficiency = 50 + (owner->getRandomGenerator()->random() % 50);
} }
if (p->game->hand->nb_cards == 0) if (p->game->hand->nb_cards == 0)
+2 -2
View File
@@ -415,7 +415,7 @@ void ActionLayer::setMenuObject(Targetable * object, bool must)
modal = 1; modal = 1;
} }
void ActionLayer::setCustomMenuObject(Targetable * object, bool must,vector<MTGAbility*>abilities) void ActionLayer::setCustomMenuObject(Targetable * object, bool must,vector<MTGAbility*>abilities,string customName)
{ {
if (!object) if (!object)
{ {
@@ -424,7 +424,7 @@ void ActionLayer::setCustomMenuObject(Targetable * object, bool must,vector<MTGA
} }
menuObject = object; menuObject = object;
SAFE_DELETE(abilitiesMenu); SAFE_DELETE(abilitiesMenu);
abilitiesMenu = NEW SimpleMenu(observer->getInput(), 10, this, Fonts::MAIN_FONT, 100, 100, object->getDisplayName().c_str()); abilitiesMenu = NEW SimpleMenu(observer->getInput(), 10, this, Fonts::MAIN_FONT, 100, 100, customName.size()?customName.c_str():object->getDisplayName().c_str());
currentActionCard = NULL; currentActionCard = NULL;
abilitiesMenu->isMultipleChoice = false; abilitiesMenu->isMultipleChoice = false;
if(abilities.size()) if(abilities.size())
+86 -7
View File
@@ -581,7 +581,7 @@ ACounterShroud::~ACounterShroud()
SAFE_DELETE(counter); SAFE_DELETE(counter);
} }
//shield a card from a certain type of counter. //track counters placed on a card
ACounterTracker::ACounterTracker(GameObserver* observer, int id, MTGCardInstance * source, MTGCardInstance * target, string scounter) : ACounterTracker::ACounterTracker(GameObserver* observer, int id, MTGCardInstance * source, MTGCardInstance * target, string scounter) :
MTGAbility(observer, id, source, target),scounter(scounter) MTGAbility(observer, id, source, target),scounter(scounter)
{ {
@@ -1112,6 +1112,47 @@ AASetCoin::~AASetCoin()
{ {
} }
//replace drawing a card with activation of an ability
ADrawReplacer::ADrawReplacer(GameObserver* observer, int id, MTGCardInstance * source, MTGAbility * replace, bool otherPlayer) :
MTGAbility(observer, id, source),re(NULL),replacer(replace),OtherPlayer(otherPlayer)
{
}
int ADrawReplacer::addToGame()
{
SAFE_DELETE(re);
if(OtherPlayer)
re = NEW REDrawReplacement(this,source->controller()->opponent(),replacer);
else
re = NEW REDrawReplacement(this,source->controller(),replacer);
if (re)
{
game->replacementEffects->add(re);
return MTGAbility::addToGame();
}
return 0;
}
int ADrawReplacer::destroy()
{
game->replacementEffects->remove(re);
SAFE_DELETE(re);
return 1;
}
ADrawReplacer * ADrawReplacer::clone() const
{
ADrawReplacer * a = NEW ADrawReplacer(*this);
a->re = NULL;
return a;
}
ADrawReplacer::~ADrawReplacer()
{
SAFE_DELETE(re);
SAFE_DELETE(replacer);
}
//Reset Damage on creatures //Reset Damage on creatures
AAResetDamage::AAResetDamage(GameObserver* observer, int id, MTGCardInstance * source, MTGCardInstance * _target, ManaCost * cost): AAResetDamage::AAResetDamage(GameObserver* observer, int id, MTGCardInstance * source, MTGCardInstance * _target, ManaCost * cost):
ActivatedAbility(observer, id, source, cost, 0) ActivatedAbility(observer, id, source, cost, 0)
@@ -1394,8 +1435,8 @@ AADiscardCard::~AADiscardCard()
SAFE_DELETE(andAbility); SAFE_DELETE(andAbility);
} }
AADrawer::AADrawer(GameObserver* observer, int _id, MTGCardInstance * card, Targetable * _target, ManaCost * _cost, string nbcardsStr, AADrawer::AADrawer(GameObserver* observer, int _id, MTGCardInstance * card, Targetable * _target, ManaCost * _cost, string nbcardsStr,
int who) : int who, bool noreplace) :
ActivatedAbilityTP(observer, _id, card, _target, _cost, who), nbcardsStr(nbcardsStr) ActivatedAbilityTP(observer, _id, card, _target, _cost, who), nbcardsStr(nbcardsStr),noReplace(noreplace)
{ {
aType = MTGAbility::STANDARD_DRAW; aType = MTGAbility::STANDARD_DRAW;
} }
@@ -1407,6 +1448,11 @@ AADrawer::AADrawer(GameObserver* observer, int _id, MTGCardInstance * card, Targ
if (player) if (player)
{ {
WParsedInt numCards(nbcardsStr, NULL, source); WParsedInt numCards(nbcardsStr, NULL, source);
WEvent * e = NEW WEventDraw(player, numCards.getValue(),this);
if(!noReplace)
e = game->replacementEffects->replace(e);
if(e)
{
game->mLayers->stackLayer()->addDraw(player, numCards.getValue()); game->mLayers->stackLayer()->addDraw(player, numCards.getValue());
game->mLayers->stackLayer()->resolve(); game->mLayers->stackLayer()->resolve();
for(int i = numCards.getValue(); i > 0;i--) for(int i = numCards.getValue(); i > 0;i--)
@@ -1415,6 +1461,8 @@ AADrawer::AADrawer(GameObserver* observer, int _id, MTGCardInstance * card, Targ
game->receiveEvent(e); game->receiveEvent(e);
} }
} }
SAFE_DELETE(e);
}
return 1; return 1;
} }
@@ -3116,8 +3164,8 @@ MayAbility::~MayAbility()
//Menu building ability Abilities //Menu building ability Abilities
//this will eventaully handle choosen discards/sacrifices. //this will eventaully handle choosen discards/sacrifices.
MenuAbility::MenuAbility(GameObserver* observer, int _id, Targetable * mtarget, MTGCardInstance * _source, bool must,vector<MTGAbility*>abilities,Player * who) : MenuAbility::MenuAbility(GameObserver* observer, int _id, Targetable * mtarget, MTGCardInstance * _source, bool must,vector<MTGAbility*>abilities,Player * who, string newName) :
MayAbility(observer, _id,NULL,_source,must), must(must),abilities(abilities),who(who) MayAbility(observer, _id,NULL,_source,must), must(must),abilities(abilities),who(who),newNameString(newName)
{ {
triggered = 0; triggered = 0;
mClone = NULL; mClone = NULL;
@@ -3129,7 +3177,7 @@ void MenuAbility::Update(float dt)
{ {
MTGAbility::Update(dt); MTGAbility::Update(dt);
ActionLayer * object = game->mLayers->actionLayer(); ActionLayer * object = game->mLayers->actionLayer();
if (!triggered && !object->menuObject) if (!triggered && !object->menuObject && !object->getCurrentTargetChooser())
{ {
triggered = 1; triggered = 1;
@@ -3146,7 +3194,7 @@ void MenuAbility::Update(float dt)
} }
if(triggered) if(triggered)
{ {
game->mLayers->actionLayer()->setCustomMenuObject(source, must,abilities); game->mLayers->actionLayer()->setCustomMenuObject(source, must,abilities,newNameString.size()?newNameString.c_str():"");
previousInterrupter = game->isInterrupting; previousInterrupter = game->isInterrupting;
game->mLayers->stackLayer()->setIsInterrupting(source->controller(), false); game->mLayers->stackLayer()->setIsInterrupting(source->controller(), false);
} }
@@ -3238,6 +3286,8 @@ MenuAbility::~MenuAbility()
if(abilities.size()) if(abilities.size())
{ {
for(int i = 0;i < int(abilities.size());i++) for(int i = 0;i < int(abilities.size());i++)
{
if(abilities[i])
{ {
AASetColorChosen * chooseA = dynamic_cast<AASetColorChosen *>(abilities[i]); AASetColorChosen * chooseA = dynamic_cast<AASetColorChosen *>(abilities[i]);
if(chooseA && chooseA->abilityAltered) if(chooseA && chooseA->abilityAltered)
@@ -3245,6 +3295,7 @@ MenuAbility::~MenuAbility()
SAFE_DELETE(abilities[i]); SAFE_DELETE(abilities[i]);
} }
} }
}
else else
SAFE_DELETE(ability); SAFE_DELETE(ability);
} }
@@ -4897,7 +4948,35 @@ PairCard * PairCard::clone() const
{ {
return NEW PairCard(*this); return NEW PairCard(*this);
} }
//target is dredged
dredgeCard::dredgeCard(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, ManaCost * _cost) :
InstantAbility(observer, id, card, target)
{
target = _target;
oneShot = true;
forceDestroy = 1;
}
int dredgeCard::resolve()
{
MTGCardInstance * _target = (MTGCardInstance *) target;
if(_target)
{
for(int j = 0; j < _target->data->dredge();j++)
{
_target->controller()->game->putInZone(
_target->controller()->game->library->cards[_target->controller()->game->library->nb_cards - 1],
_target->controller()->game->library, _target->controller()->game->graveyard);
}
_target->controller()->game->putInZone(_target,_target->currentZone,_target->controller()->game->hand);
}
return 1;
}
dredgeCard * dredgeCard::clone() const
{
return NEW dredgeCard(*this);
}
// target becomes a parent of card(source) // target becomes a parent of card(source)
AAConnect::AAConnect(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, ManaCost * _cost) : AAConnect::AAConnect(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, ManaCost * _cost) :
+7
View File
@@ -58,6 +58,7 @@ CardPrimitive::CardPrimitive(CardPrimitive * source)
toughness = source->toughness; toughness = source->toughness;
restrictions = source->restrictions ? source->restrictions->clone() : NULL; restrictions = source->restrictions ? source->restrictions->clone() : NULL;
suspendedTime = source->suspendedTime; suspendedTime = source->suspendedTime;
dredgeAmount = source->dredgeAmount;
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)
@@ -82,6 +83,7 @@ int CardPrimitive::init()
spellTargetType = ""; spellTargetType = "";
alias = 0; alias = 0;
restrictions = NULL; restrictions = NULL;
dredgeAmount = 0;
return 1; return 1;
} }
@@ -100,6 +102,11 @@ bool CardPrimitive::isSpell()
return (!isCreature() && !isLand()); return (!isCreature() && !isLand());
} }
int CardPrimitive::dredge()
{
return dredgeAmount;
}
void CardPrimitive::setRestrictions(string _restriction) void CardPrimitive::setRestrictions(string _restriction)
{ {
if (!restrictions) if (!restrictions)
+43 -2
View File
@@ -961,13 +961,20 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
observer->addObserver(NEW MTGBlockRule(observer, -1)); observer->addObserver(NEW MTGBlockRule(observer, -1));
return NULL; return NULL;
} }
//this rule handles blocking ability during blocker phase //this rule handles cards that have soulbond
found = s.find("soulbondrule"); found = s.find("soulbondrule");
if(found != string::npos) if(found != string::npos)
{ {
observer->addObserver(NEW MTGSoulbondRule(observer, -1)); observer->addObserver(NEW MTGSoulbondRule(observer, -1));
return NULL; return NULL;
} }
//this rule handles cards that have dredge
found = s.find("dredgerule");
if(found != string::npos)
{
observer->replacementEffects->add(NEW MTGDredgeRule(observer, -1));
return NULL;
}
//this rule handles combat related triggers. note, combat related triggered abilities will not work without it. //this rule handles combat related triggers. note, combat related triggered abilities will not work without it.
found = s.find("combattriggerrule"); found = s.find("combattriggerrule");
if(found != string::npos) if(found != string::npos)
@@ -1700,6 +1707,30 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
return NULL; return NULL;
} }
//opponent replace draw with
found = s.find("opponentreplacedraw ");
if (found != string::npos)
{
string s1 = s.substr(found + 19);
MTGAbility * a = NULL;
a = parseMagicLine(s1, id, spell, card, false, activated);
if(a)
return NEW ADrawReplacer(observer,id, card,a,true);
return NULL;
}
//replace draw with
found = s.find("replacedraw ");
if (found != string::npos)
{
string s1 = s.substr(found + 11);
MTGAbility * a = NULL;
a = parseMagicLine(s1, id, spell, card, false, activated);
if(a)
return NEW ADrawReplacer(observer,id, card,a);
return NULL;
}
if (!activated && tc) if (!activated && tc)
{ {
MTGAbility * a = parseMagicLine(sWithoutTc, id, spell, card); MTGAbility * a = parseMagicLine(sWithoutTc, id, spell, card);
@@ -1870,9 +1901,19 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
{ {
if (storedAbilityString.size()) if (storedAbilityString.size())
{ {
vector<string> splitName = parseBetween(storedAbilityString, "name(", ")");
if (splitName.size())
{
newName = splitName[1];
storedAbilityString = splitName[0];
storedAbilityString.append(splitName[2]);
//we erase the name section from the string to avoid
//accidently building an mtg ability with the text meant for menuText.
}
ATargetedAbilityCreator * abl = NEW ATargetedAbilityCreator(observer, id, card,target, NULL,newName, storedAbilityString, who); ATargetedAbilityCreator * abl = NEW ATargetedAbilityCreator(observer, id, card,target, NULL,newName, storedAbilityString, who);
abl->oneShot = 1; abl->oneShot = 1;
storedString.clear(); storedString.clear();
storedAbilityString.clear();
return abl; return abl;
} }
} }
@@ -2228,7 +2269,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
if (splitDraw.size()) if (splitDraw.size())
{ {
Targetable * t = spell ? spell->getNextTarget() : NULL; Targetable * t = spell ? spell->getNextTarget() : NULL;
MTGAbility * a = NEW AADrawer(observer, id, card, t, NULL,splitDraw[1], who); MTGAbility * a = NEW AADrawer(observer, id, card, t, NULL,splitDraw[1], who,s.find("noreplace") != string::npos);
a->oneShot = 1; a->oneShot = 1;
return a; return a;
} }
+1
View File
@@ -163,6 +163,7 @@ void MTGCardInstance::initMTGCI()
mPropertiesChangedSinceLastUpdate = false; mPropertiesChangedSinceLastUpdate = false;
stillNeeded = true; stillNeeded = true;
kicked = 0; kicked = 0;
dredge = 0;
chooseacolor = -1; chooseacolor = -1;
chooseasubtype = ""; chooseasubtype = "";
coinSide = -1; coinSide = -1;
+10
View File
@@ -119,7 +119,17 @@ int MTGAllCards::processConfLine(string &s, MTGCard *card, CardPrimitive * primi
} }
} }
break; break;
case 'd'://dredge
if (!primitive) primitive = NEW CardPrimitive();
{
string value = val;
std::transform(value.begin(), value.end(), value.begin(), ::tolower);
vector<string> values = parseBetween(value,"dredge(",")");
if(values.size())
primitive->dredgeAmount = atoi(values[1].c_str());
break;
}
case 'f': //flashback//morph case 'f': //flashback//morph
{ {
if (!primitive) primitive = NEW CardPrimitive(); if (!primitive) primitive = NEW CardPrimitive();
+100
View File
@@ -2098,7 +2098,107 @@ MTGSoulbondRule * MTGSoulbondRule::clone() const
{ {
return NEW MTGSoulbondRule(*this); return NEW MTGSoulbondRule(*this);
} }
/*dredge*/
MTGDredgeRule::MTGDredgeRule(GameObserver* observer, int _id) :
PermanentAbility(observer, _id)
{
tcb = NULL;
dredgeAbility = NULL;
targetAbility = NULL;
mod = NULL;
}
;
WEvent * MTGDredgeRule::replace(WEvent * event)
{
WEventDraw * e = dynamic_cast<WEventDraw*> (event);
if (e)
{
MTGCardInstance * card = NULL;
if(e->player->game->library->nb_cards)
card = e->player->game->library->cards[e->player->game->library->nb_cards-1];
if(!card)
return event;
TargetChooserFactory tf(e->player->getObserver());
tcb = tf.createTargetChooser("dredgeable",card);
tcb->targetter = NULL;
if(!tcb->validTargetsExist())
{
SAFE_DELETE(tcb);
return event;
}
SAFE_DELETE(tcb);
for (int i = 0; i < 2; i++)
{
Player * p = game->players[i];
if (e->player == p)
{
for(int draw = 0;draw < e->nb_cards;draw++)
{
tcb = tf.createTargetChooser("dredgeable",card);
tcb->targetter = NULL;
vector<MTGAbility*>selection;
//look for other draw replacement effects
list<ReplacementEffect *>::iterator it;
for (it = game->replacementEffects->modifiers.begin(); it != game->replacementEffects->modifiers.end(); it++)
{
ReplacementEffect *re = *it;
if(REDrawReplacement * DR = dynamic_cast<REDrawReplacement *>(*it))
{
MTGAbility * otherA = NULL;
if(DR->DrawerOfCard == p)
if(DR->replacementAbility->oneShot)
selection.push_back(DR->replacementAbility->clone());
else
{
otherA = NEW GenericAddToGame(game, game->mLayers->actionLayer()->getMaxId(),DR->replacementAbility->source,NULL,DR->replacementAbility->clone());
selection.push_back(otherA);
}
}
}
//there is a memleak here that i have no idea what causes it.
dredgeAbility = NEW dredgeCard(game, game->mLayers->actionLayer()->getMaxId(), card,NULL);
dredgeAbility->oneShot = true;
targetAbility = NEW GenericTargetAbility(game, "Dredge A Card","",game->mLayers->actionLayer()->getMaxId(), card,tcb->clone(),dredgeAbility->clone());
targetAbility->oneShot = true;
SAFE_DELETE(dredgeAbility);
targetAbilityAdder = NEW GenericAddToGame(game, game->mLayers->actionLayer()->getMaxId(), card,NULL,targetAbility->clone());
targetAbilityAdder->oneShot = true;
SAFE_DELETE(targetAbility);
MTGAbility * setDredge = targetAbilityAdder->clone();
SAFE_DELETE(targetAbilityAdder);
setDredge->oneShot = true;
selection.push_back(setDredge);
targetAbility1 = NEW AADrawer(game, this->GetId(), card,card,NULL, "1",TargetChooser::CONTROLLER,true);
selection.push_back(targetAbility1);
MTGAbility * menuChoice = NEW MenuAbility(game, this->GetId(), card, card,true,selection,card->controller(),"Dredge or Draw");
menuChoice->addToGame();
SAFE_DELETE(tcb);
}
SAFE_DELETE(event);
return event;
}
}
}
return event;
}
ostream& MTGDredgeRule::toString(ostream& out) const
{
out << "MTGDredgeRule ::: (";
return MTGAbility::toString(out) << ")";
}
MTGDredgeRule * MTGDredgeRule::clone() const
{
return NEW MTGDredgeRule(*this);
}
/* Persist */ /* Persist */
MTGPersistRule::MTGPersistRule(GameObserver* observer, int _id) : MTGPersistRule::MTGPersistRule(GameObserver* observer, int _id) :
PermanentAbility(observer, _id) PermanentAbility(observer, _id)
+75
View File
@@ -77,6 +77,81 @@ RECountersPrevention::~RECountersPrevention()
{ {
SAFE_DELETE(TargetingCards); SAFE_DELETE(TargetingCards);
} }
////--draw replacement---------------------
REDrawReplacement::REDrawReplacement(MTGAbility * source, Player * Drawer, MTGAbility * replaceWith) :
source(source), DrawerOfCard(Drawer),replacementAbility(replaceWith)
{
}
WEvent * REDrawReplacement::replace(WEvent *event)
{
if (!event) return event;
WEventDraw * e = dynamic_cast<WEventDraw*> (event);
if (!e) return event;
if (DrawerOfCard != e->player) return event;
if(!replacementAbility) return event;
//check for dredge
TargetChooserFactory tf(e->player->getObserver());
TargetChooser * tcb = NULL;
tcb = tf.createTargetChooser("dredgeable",source->source);
tcb->targetter = NULL;
if(tcb->validTargetsExist())
{
if(e->player == DrawerOfCard && e->player == source->source->controller())
{
SAFE_DELETE(tcb);
return event;
}
}
SAFE_DELETE(tcb);
vector<MTGAbility*>selection;
//look for other draw replacement effects
list<ReplacementEffect *>::iterator it;
GameObserver * game = source->source->getObserver();
if(replacementAbility->source->controller() == DrawerOfCard)
for (it = game->replacementEffects->modifiers.begin(); it != game->replacementEffects->modifiers.end(); it++)
{
ReplacementEffect *re = *it;
if(REDrawReplacement * DR = dynamic_cast<REDrawReplacement *>(*it))
{
MTGAbility * otherA = NULL;
if(DR->DrawerOfCard == e->player)
if(DR->replacementAbility->oneShot)
selection.push_back(DR->replacementAbility->clone());
else
{
otherA = NEW GenericAddToGame(game, game->mLayers->actionLayer()->getMaxId(), source->source,NULL,DR->replacementAbility->clone());
selection.push_back(otherA);
}
}
}
for(int j = 0; j < e->nb_cards; j++)
{
if(e->player != DrawerOfCard || selection.size() < 2)
{
MTGAbility * toResolve = replacementAbility->clone();
if(replacementAbility->oneShot)
toResolve->resolve();
else
toResolve->addToGame();
}
else
{
MTGAbility * menuChoice = NEW MenuAbility(game, 1, source->source, source->source,true,selection,NULL,"Choose Draw Replacement");
menuChoice->addToGame();
}
}
delete event;
event = NULL;
return event;
}
REDrawReplacement::~REDrawReplacement()
{
}
////////////////////////////////////////////// //////////////////////////////////////////////
ReplacementEffects::ReplacementEffects() ReplacementEffects::ReplacementEffects()
{ {
+37
View File
@@ -32,6 +32,14 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta
return NEW pairableChooser(observer, card, maxtargets); return NEW pairableChooser(observer, card, maxtargets);
} }
found = s.find("dredgeable");
if (found != string::npos)
{
int maxtargets = 1;
zones[nbzones++] = MTGGameZone::MY_GRAVEYARD;
return NEW dredgeChooser(observer,zones,nbzones, card, maxtargets);
}
found = s.find("mytgt"); found = s.find("mytgt");
if (found == 0) if (found == 0)
{ {
@@ -1601,6 +1609,35 @@ bool pairableChooser::equals(TargetChooser * tc)
return TypeTargetChooser::equals(tc); return TypeTargetChooser::equals(tc);
} }
//*Dredge targetchooser*//
bool dredgeChooser::canTarget(Targetable * target,bool withoutProtections)
{
if (MTGCardInstance * card = dynamic_cast<MTGCardInstance*>(target))
{
if((card->data->dredgeAmount < 1) || (card->data->dredgeAmount > card->controller()->game->library->nb_cards))
return false;
if(card->currentZone == card->controller()->game->graveyard)
return true;
}
return false;
}
dredgeChooser* dredgeChooser::clone() const
{
dredgeChooser * a = NEW dredgeChooser(*this);
return a;
}
bool dredgeChooser::equals(TargetChooser * tc)
{
dredgeChooser * dtc = dynamic_cast<dredgeChooser *> (tc);
if (!dtc)
return false;
return TypeTargetChooser::equals(tc);
}
//-----------
//----------- //-----------
/*Proliferate Target */ /*Proliferate Target */
bool ProliferateChooser::canTarget(Targetable * target,bool withoutProtections) bool ProliferateChooser::canTarget(Targetable * target,bool withoutProtections)
+5
View File
@@ -91,6 +91,11 @@ WEventCardBlocked::WEventCardBlocked(MTGCardInstance * card,MTGCardInstance * op
WEventcardDraw::WEventcardDraw(Player * player, int nb_cards) : WEventcardDraw::WEventcardDraw(Player * player, int nb_cards) :
player(player), nb_cards(nb_cards) player(player), nb_cards(nb_cards)
{ {
}
WEventDraw::WEventDraw(Player * player, int nb_cards,MTGAbility * cardDraw) ://happens at the call for drawfromlibrary
player(player), nb_cards(nb_cards),drawAbility(cardDraw)
{
} }
WEventCardSacrifice::WEventCardSacrifice(MTGCardInstance * card, MTGCardInstance * after) : WEventCardSacrifice::WEventCardSacrifice(MTGCardInstance * card, MTGCardInstance * after) :