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

View File

@@ -44,7 +44,7 @@ public:
int reactToTargetClick(ActionElement * ability, Targetable * card);
int stillInUse(MTGCardInstance * card);
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 ButtonPressedOnMultipleChoice(int choice = -1);
void doReactTo(int menuIndex);

View File

@@ -1105,7 +1105,8 @@ public:
MTGAbility * mClone;
vector<MTGAbility*>abilities;
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);
int resolve();
const char * getMenuText();
@@ -1393,9 +1394,9 @@ class AADrawer: public ActivatedAbilityTP
public:
string nbcardsStr;
bool noReplace;
AADrawer(GameObserver* observer, int _id, MTGCardInstance * card, Targetable * _target, ManaCost * _cost,string nbcardsStr, int who =
TargetChooser::UNSET);
TargetChooser::UNSET,bool noReplace = false);
int resolve();
const char * getMenuText();
AADrawer * clone() const;
@@ -2622,7 +2623,14 @@ public:
int resolve();
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 */
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
*/

View File

@@ -66,6 +66,7 @@ public:
int power;
int toughness;
int suspendedTime;
int dredgeAmount;
vector<int>types;
CardPrimitive();
@@ -110,7 +111,7 @@ public:
bool isCreature();
bool isLand();
bool isSpell();
int dredge();
void setPower(int _power);
int getPower();
void setToughness(int _toughness);

View File

@@ -99,6 +99,7 @@ public:
int fresh;
int MaxLevelUp;
int kicked;
int dredge;
bool isDualWielding;
bool stillNeeded;
Player * lastController;

View File

@@ -272,6 +272,24 @@ public:
virtual ostream& toString(ostream& out) 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 */
class MTGPersistRule: public PermanentAbility
{

View File

@@ -49,12 +49,22 @@ public:
WEvent * replace(WEvent *e);
~RECountersPrevention();
};
class ReplacementEffects
class REDrawReplacement: public ReplacementEffect
{
protected:
list<ReplacementEffect *> modifiers;
MTGAbility * source;
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();
WEvent * replace(WEvent *e);
int add(ReplacementEffect * re);

View File

@@ -298,6 +298,25 @@ public:
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
{
public:

View File

@@ -12,6 +12,8 @@ class Targetable;
class ManaPool;
class AACounter;
class Counters;
class MTGAbility;
class DrawAction;
class WEvent {
public:
@@ -221,7 +223,13 @@ struct WEventcardDraw : public WEvent {
int nb_cards;
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
//exchangeWith: exchange card's position with exchangeWith's position
//attacker:both card and exchangeWith *should* be in attacker's "blockers" list.

View File

@@ -602,7 +602,7 @@ int OrderedAIAction::getEfficiency()
if (!efficiency && may)
{
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);
}
if (p->game->hand->nb_cards == 0)

View File

@@ -415,7 +415,7 @@ void ActionLayer::setMenuObject(Targetable * object, bool must)
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)
{
@@ -424,7 +424,7 @@ void ActionLayer::setCustomMenuObject(Targetable * object, bool must,vector<MTGA
}
menuObject = object;
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;
abilitiesMenu->isMultipleChoice = false;
if(abilities.size())

View File

@@ -467,7 +467,7 @@ int DrawAction::resolve()
{
for (int i = 0; i < nbcards; i++)
{
player->game->drawFromLibrary();
player->game->drawFromLibrary();
}
return 1;
}

View File

@@ -581,7 +581,7 @@ ACounterShroud::~ACounterShroud()
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) :
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
AAResetDamage::AAResetDamage(GameObserver* observer, int id, MTGCardInstance * source, MTGCardInstance * _target, ManaCost * cost):
ActivatedAbility(observer, id, source, cost, 0)
@@ -1394,8 +1435,8 @@ AADiscardCard::~AADiscardCard()
SAFE_DELETE(andAbility);
}
AADrawer::AADrawer(GameObserver* observer, int _id, MTGCardInstance * card, Targetable * _target, ManaCost * _cost, string nbcardsStr,
int who) :
ActivatedAbilityTP(observer, _id, card, _target, _cost, who), nbcardsStr(nbcardsStr)
int who, bool noreplace) :
ActivatedAbilityTP(observer, _id, card, _target, _cost, who), nbcardsStr(nbcardsStr),noReplace(noreplace)
{
aType = MTGAbility::STANDARD_DRAW;
}
@@ -1403,17 +1444,24 @@ AADrawer::AADrawer(GameObserver* observer, int _id, MTGCardInstance * card, Targ
int AADrawer::resolve()
{
Player * player = getPlayerFromTarget(getTarget());
if (player)
{
WParsedInt numCards(nbcardsStr, NULL, source);
game->mLayers->stackLayer()->addDraw(player, numCards.getValue());
game->mLayers->stackLayer()->resolve();
for(int i = numCards.getValue(); i > 0;i--)
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()->resolve();
for(int i = numCards.getValue(); i > 0;i--)
{
WEvent * e = NEW WEventcardDraw(player, 1);
game->receiveEvent(e);
}
}
SAFE_DELETE(e);
}
return 1;
}
@@ -3116,8 +3164,8 @@ MayAbility::~MayAbility()
//Menu building ability Abilities
//this will eventaully handle choosen discards/sacrifices.
MenuAbility::MenuAbility(GameObserver* observer, int _id, Targetable * mtarget, MTGCardInstance * _source, bool must,vector<MTGAbility*>abilities,Player * who) :
MayAbility(observer, _id,NULL,_source,must), must(must),abilities(abilities),who(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),newNameString(newName)
{
triggered = 0;
mClone = NULL;
@@ -3129,7 +3177,7 @@ void MenuAbility::Update(float dt)
{
MTGAbility::Update(dt);
ActionLayer * object = game->mLayers->actionLayer();
if (!triggered && !object->menuObject)
if (!triggered && !object->menuObject && !object->getCurrentTargetChooser())
{
triggered = 1;
@@ -3146,7 +3194,7 @@ void MenuAbility::Update(float dt)
}
if(triggered)
{
game->mLayers->actionLayer()->setCustomMenuObject(source, must,abilities);
game->mLayers->actionLayer()->setCustomMenuObject(source, must,abilities,newNameString.size()?newNameString.c_str():"");
previousInterrupter = game->isInterrupting;
game->mLayers->stackLayer()->setIsInterrupting(source->controller(), false);
}
@@ -3239,10 +3287,13 @@ MenuAbility::~MenuAbility()
{
for(int i = 0;i < int(abilities.size());i++)
{
AASetColorChosen * chooseA = dynamic_cast<AASetColorChosen *>(abilities[i]);
if(chooseA && chooseA->abilityAltered)
SAFE_DELETE(chooseA->abilityAltered);
SAFE_DELETE(abilities[i]);
if(abilities[i])
{
AASetColorChosen * chooseA = dynamic_cast<AASetColorChosen *>(abilities[i]);
if(chooseA && chooseA->abilityAltered)
SAFE_DELETE(chooseA->abilityAltered);
SAFE_DELETE(abilities[i]);
}
}
}
else
@@ -4897,7 +4948,35 @@ PairCard * PairCard::clone() const
{
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)
AAConnect::AAConnect(GameObserver* observer, int id, MTGCardInstance * card, MTGCardInstance * _target, ManaCost * _cost) :

View File

@@ -58,6 +58,7 @@ CardPrimitive::CardPrimitive(CardPrimitive * source)
toughness = source->toughness;
restrictions = source->restrictions ? source->restrictions->clone() : NULL;
suspendedTime = source->suspendedTime;
dredgeAmount = source->dredgeAmount;
magicText = source->magicText;
for (map<string, string>::const_iterator it = source->magicTexts.begin(); it != source->magicTexts.end(); ++it)
@@ -82,6 +83,7 @@ int CardPrimitive::init()
spellTargetType = "";
alias = 0;
restrictions = NULL;
dredgeAmount = 0;
return 1;
}
@@ -100,6 +102,11 @@ bool CardPrimitive::isSpell()
return (!isCreature() && !isLand());
}
int CardPrimitive::dredge()
{
return dredgeAmount;
}
void CardPrimitive::setRestrictions(string _restriction)
{
if (!restrictions)

View File

@@ -961,13 +961,20 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
observer->addObserver(NEW MTGBlockRule(observer, -1));
return NULL;
}
//this rule handles blocking ability during blocker phase
//this rule handles cards that have soulbond
found = s.find("soulbondrule");
if(found != string::npos)
{
observer->addObserver(NEW MTGSoulbondRule(observer, -1));
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.
found = s.find("combattriggerrule");
if(found != string::npos)
@@ -1700,6 +1707,30 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
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)
{
MTGAbility * a = parseMagicLine(sWithoutTc, id, spell, card);
@@ -1870,9 +1901,19 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
{
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);
abl->oneShot = 1;
storedString.clear();
storedAbilityString.clear();
return abl;
}
}
@@ -2228,7 +2269,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
if (splitDraw.size())
{
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;
return a;
}

View File

@@ -163,6 +163,7 @@ void MTGCardInstance::initMTGCI()
mPropertiesChangedSinceLastUpdate = false;
stillNeeded = true;
kicked = 0;
dredge = 0;
chooseacolor = -1;
chooseasubtype = "";
coinSide = -1;

View File

@@ -119,7 +119,17 @@ int MTGAllCards::processConfLine(string &s, MTGCard *card, CardPrimitive * primi
}
}
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
{
if (!primitive) primitive = NEW CardPrimitive();

View File

@@ -2098,7 +2098,107 @@ MTGSoulbondRule * MTGSoulbondRule::clone() const
{
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 */
MTGPersistRule::MTGPersistRule(GameObserver* observer, int _id) :
PermanentAbility(observer, _id)

View File

@@ -77,6 +77,81 @@ RECountersPrevention::~RECountersPrevention()
{
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()
{

View File

@@ -32,6 +32,14 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta
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");
if (found == 0)
{
@@ -1601,6 +1609,35 @@ bool pairableChooser::equals(TargetChooser * 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 */
bool ProliferateChooser::canTarget(Targetable * target,bool withoutProtections)

View File

@@ -91,6 +91,11 @@ WEventCardBlocked::WEventCardBlocked(MTGCardInstance * card,MTGCardInstance * op
WEventcardDraw::WEventcardDraw(Player * player, int 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) :