massive update, additions and changelog in first comment.

This commit is contained in:
omegablast2002@yahoo.com
2010-10-18 10:46:36 +00:00
parent 211deca011
commit d13e8904b5
33 changed files with 1539 additions and 85 deletions
+2 -3
View File
@@ -101,8 +101,7 @@ void ActionLayer::Update(float dt){
cantCancel = 0;
cancelCurrentAction();
}
}
}
}
void ActionLayer::Render (){
@@ -120,7 +119,7 @@ void ActionLayer::Render (){
void ActionLayer::setCurrentWaitingAction(ActionElement * ae){
assert(!ae || !currentWaitingAction);
assert(!ae || !currentWaitingAction);//this assert causes crashes when may abilities overlap each other on ai. this conidiation is preexsiting.
currentWaitingAction = ae;
if (!ae) cantCancel = 0;
}
+13 -3
View File
@@ -215,7 +215,6 @@ bool Spell::RetraceWasPaid(){
const string Spell::getDisplayName() const {
return source->getName();
}
Spell::~Spell(){
SAFE_DELETE(cost);
SAFE_DELETE(tc);
@@ -390,7 +389,10 @@ int ActionStack::addAbility(MTGAbility * ability){
int ActionStack::addDraw(Player * player, int nb_cards){
DrawAction * draw = NEW DrawAction(mCount,player, nb_cards);
addAction(draw);
addAction(draw);
GameObserver *g = GameObserver::GetInstance();
WEvent * e = NEW WEventcardDraw(player,nb_cards);
g->receiveEvent(e);
return 1;
}
@@ -405,11 +407,19 @@ int ActionStack::AddNextGamePhase(){
NextGamePhase * next = NEW NextGamePhase(mCount);
addAction(next);
int playerId = 0;
if (game->currentActionPlayer == game->players[1]) playerId = 1;
game->currentActionPlayer = game->GetInstance()->currentActionPlayer;
if (game->currentActionPlayer == game->players[1]){ playerId = 1;}
interruptDecision[playerId] = 1;
return 1;
}
int ActionStack::AddNextCombatStep(){
if (getNext(NULL,NOT_RESOLVED)) return 0;
NextGamePhase * next = NEW NextGamePhase(mCount);
addAction(next);
return 1;
}
int ActionStack::setIsInterrupting(Player * player){
if (player == game->players[0]){
interruptDecision[0] = -1;
+8 -2
View File
@@ -34,6 +34,10 @@ void CardDescriptor::unsecureSetTapped(int i){
tapped = i;
}
void CardDescriptor::unsecuresetfresh(int k){
fresh = k;
}
void CardDescriptor::setNegativeSubtype( string value){
int id = Subtypes::subtypesList->find(value);
addType(-id);
@@ -150,15 +154,17 @@ MTGCardInstance * CardDescriptor::match(MTGCardInstance * card){
}
}
if ((tapped == -1 && card->isTapped()) || (tapped == 1 && !card->isTapped())){
match = NULL;
}
if ((fresh == -1 && card->fresh) || (fresh == 1 && !card->fresh)){
match = NULL;
}
if ((isToken== -1 && card->isToken) || (isToken == 1 && !card->isToken)){
match = NULL;
}
if (attacker == 1){
if (defenser == &AnyCard){
if (!card->attacker && !card->defenser) match = NULL;
+4 -3
View File
@@ -114,6 +114,7 @@ void CardGui::Render()
else if (card->hasSubtype("island"))
icon = resources.GetQuad("c_blue");
if (icon){
icon->SetColor(ARGB(static_cast<unsigned char>(actA),255,255,255));
renderer->RenderQuad(icon, actX, actY, 0);
@@ -125,7 +126,7 @@ void CardGui::Render()
if (card->isCreature()){
mFont->SetScale(DEFAULT_MAIN_FONT_SCALE);
char buffer[200];
sprintf(buffer, "%i/%i",card->power,card->life);
sprintf(buffer, "%i/%i",card->power,card->life);
renderer->FillRect(actX - (12*actZ) , actY + 6* actZ, 25*actZ, 12*actZ, ARGB(((static_cast<unsigned char>(actA))/2),0,0,0));
mFont->SetColor(ARGB(static_cast<unsigned char>(actA),255,255,255));
mFont->SetScale(actZ);
@@ -588,7 +589,7 @@ void CardGui::RenderBig(MTGCard* card, const Pos& pos){
if (quad->mHeight < quad->mWidth) {
return tinyCropRender(card, pos, quad);
}
quad->SetColor(ARGB((int)pos.actA,255,255,255));
quad->SetColor(ARGB(255,255,255,255));
float scale = pos.actZ * 257.f / quad->mHeight;
renderer->RenderQuad(quad, x, pos.actY, pos.actT, scale, scale);
return;
@@ -599,7 +600,7 @@ void CardGui::RenderBig(MTGCard* card, const Pos& pos){
if ((q = resources.RetrieveCard(card,CACHE_THUMB)))
{
float scale = pos.actZ * 250 / q->mHeight;
q->SetColor(ARGB((int)pos.actA,255,255,255));
q->SetColor(ARGB(255,255,255,255));
renderer->RenderQuad(q, x, pos.actY, pos.actT, scale, scale);
return;
}
+2 -5
View File
@@ -32,7 +32,6 @@ int Damage::resolve(){
state = RESOLVED_OK;
GameObserver * g = GameObserver::GetInstance();
WEvent * e = NEW WEventDamage(this);
//Replacement Effects
e = g->replacementEffects->replace(e);
if (!e) return 0;
@@ -114,7 +113,6 @@ int Damage::resolve(){
// Poison on player
Player * _target = (Player *)target;
_target->poisonCount += damage;//this will be changed to poison counters.
} else if (target->type_as_damageable == DAMAGEABLE_PLAYER &&
( source->has(Constants::POISONTOXIC) || source->has(Constants::POISONTWOTOXIC) || source->has(Constants::POISONTHREETOXIC) )) {
//Damage + 1, 2, or 3 poison counters on player
@@ -188,11 +186,10 @@ int DamageStack::resolve(){
for (int i = mCount-1; i>= 0; i--){
Damage * damage = (Damage*)mObjects[i];
if (damage->state == NOT_RESOLVED) damage->resolve();
}
}
GameObserver::GetInstance()->receiveEvent(NEW WEventDamageStackResolved());
return 1;
}
}
int DamageStack::receiveEvent(WEvent * e) {
WEventDamageStackResolved *event = dynamic_cast<WEventDamageStackResolved*>(e);
+1
View File
@@ -57,6 +57,7 @@ void DamagerDamaged::Render(CombatStep mode)
switch (mode)
{
case BLOCKERS :
case TRIGGERS :
case ORDER :
mFont->SetColor(ARGB(92,255,255,255));
break;
+1
View File
@@ -27,6 +27,7 @@ void DuelLayers::init(){
action->Add(NEW MTGRetraceRule(-1));
action->Add(NEW MTGAttackRule(-1));
action->Add(NEW MTGBlockRule(-1));
action->Add(NEW MTGCombatTriggersRule(-1));
action->Add(NEW MTGLegendRule(-1));
action->Add(NEW MTGTokensCleanup(-1)); // needs to be before persist
action->Add(NEW MTGPersistRule(-1));
+65 -3
View File
@@ -23,8 +23,7 @@ int ExtraCost::setSource(MTGCardInstance * _source){
if (tc)
{
tc->source = _source;
// Cryptic comment from cloned/refactored code:
// "Tapping targets is not targetting, protections do not apply"
// "extra cost is not targetting, protections do not apply" this is not cryptic at all :) make an ability you will understand it then. this keeps the target chooser from being unable to select a creature with shroud/protections.
tc->targetter = NULL;
}
else
@@ -93,19 +92,46 @@ int DiscardRandomCost::canPay(){
MTGGameZone * z = target->controller()->game->hand;
int nbcards = z->nb_cards;
if(nbcards < 1) return 0;
if(nbcards == 1 && z->hasCard(source)) return 0;
return 1;
}
int DiscardRandomCost::doPay(){
MTGCardInstance * _target = (MTGCardInstance *) target;
if(target){
_target->controller()->game->discardRandom(_target->controller()->game->hand);
_target->controller()->game->discardRandom(_target->controller()->game->hand,source);
target = NULL;
if (tc) tc->initTargets();
return 1;
}
return 0;
}
//a choosen discard
DiscardCost * DiscardCost::clone() const{
DiscardCost * ec = NEW DiscardCost(*this);
if (tc) ec->tc = tc->clone();
return ec;
}
DiscardCost::DiscardCost(TargetChooser *_tc)
: ExtraCost("Choose card to Discard", _tc){
}
int DiscardCost::doPay(){
MTGCardInstance * _target = (MTGCardInstance *) target;
if(target){
WEvent * e = NEW WEventCardDiscard(target);
GameObserver * game = GameObserver::GetInstance();
game->receiveEvent(e);
_target->controller()->game->putInGraveyard(_target);
target = NULL;
if (tc) tc->initTargets();
return 1;
}
return 0;
}
//to library cost
ToLibraryCost * ToLibraryCost::clone() const{
ToLibraryCost * ec = NEW ToLibraryCost(*this);
@@ -242,6 +268,39 @@ int BounceTargetCost::doPay(){
return 0;
}
//Bounce as cost for ninja
Ninja * Ninja::clone() const{
Ninja * ec = NEW Ninja(*this);
if (tc) ec->tc = tc->clone();
return ec;
}
Ninja::Ninja(TargetChooser *_tc)
: ExtraCost("Select unblocked attacker", _tc){
}
int Ninja::isPaymentSet(){
GameObserver * g = GameObserver::GetInstance();
int currentPhase = g->getCurrentGamePhase();
if (target && ((target->isAttacker() && target->blocked == true) || target->isAttacker() < 1 || currentPhase != Constants::MTG_PHASE_COMBATBLOCKERS)){ tc->removeTarget(target);target = NULL; return 0;}
if(target) return 1;
return 0;
}
int Ninja::doPay(){
MTGCardInstance * _target = (MTGCardInstance *) target;
if(target){
target->controller()->game->putInHand(target);
target = NULL;
if (tc) tc->initTargets();
return 1;
}
return 0;
}
//endbouncetargetcostforninja
//------------------------------------------------------------
SacrificeCost * SacrificeCost::clone() const{
SacrificeCost * ec = NEW SacrificeCost(*this);
if (tc) ec->tc = tc->clone();
@@ -254,6 +313,9 @@ SacrificeCost::SacrificeCost(TargetChooser *_tc)
int SacrificeCost::doPay(){
if(target){
WEvent * e = NEW WEventCardSacrifice(target);
GameObserver * game = GameObserver::GetInstance();
game->receiveEvent(e);
target->controller()->game->putInGraveyard(target);
target = NULL;
if (tc) tc->initTargets();
+38 -12
View File
@@ -74,16 +74,17 @@ void GameObserver::nextGamePhase(){
if (FIRST_STRIKE == combatStep || END_FIRST_STRIKE == combatStep || DAMAGE == combatStep) {
nextCombatStep(); return;
}
if (cPhaseOld->id == Constants::MTG_PHASE_COMBATBLOCKERS)
if (BLOCKERS == combatStep) { nextCombatStep(); return; }
if (BLOCKERS == combatStep || TRIGGERS == combatStep) { nextCombatStep(); return; }
phaseRing->forward();
//Go directly to end of combat if no attackers
if (cPhaseOld->id == Constants::MTG_PHASE_COMBATATTACKERS && !(currentPlayer->game->inPlay->getNextAttacker(NULL))){
phaseRing->forward();
phaseRing->forward();
}
}
Phase * cPhase = phaseRing->getCurrentPhase();
currentGamePhase = cPhase->id;
@@ -151,8 +152,12 @@ void GameObserver::nextCombatStep()
{
switch (combatStep)
{
case BLOCKERS : receiveEvent(NEW WEventBlockersChosen());
receiveEvent(NEW WEventCombatStepChange(combatStep = ORDER)); return;
case BLOCKERS :
receiveEvent(NEW WEventBlockersChosen());
receiveEvent(NEW WEventCombatStepChange(combatStep = TRIGGERS));
return;
case TRIGGERS : receiveEvent(NEW WEventCombatStepChange(combatStep = ORDER)); return;
case ORDER : receiveEvent(NEW WEventCombatStepChange(combatStep = FIRST_STRIKE)); return;
case FIRST_STRIKE : receiveEvent(NEW WEventCombatStepChange(combatStep = END_FIRST_STRIKE)); return;
case END_FIRST_STRIKE : receiveEvent(NEW WEventCombatStepChange(combatStep = DAMAGE)); return;
@@ -164,17 +169,27 @@ void GameObserver::nextCombatStep()
void GameObserver::userRequestNextGamePhase(){
if (mLayers->stackLayer()->getNext(NULL,0,NOT_RESOLVED)) return;
if (getCurrentTargetChooser()) return;
bool executeNextPhaseImmediately = true;
Phase * cPhaseOld = phaseRing->getCurrentPhase();
if ((cPhaseOld->id == Constants::MTG_PHASE_COMBATBLOCKERS && combatStep == ORDER) ||
(cPhaseOld->id == Constants::MTG_PHASE_COMBATBLOCKERS && combatStep == TRIGGERS)||
cPhaseOld->id == Constants::MTG_PHASE_COMBATDAMAGE ||
opponent()->isAI() ||
options[Options::optionInterrupt(currentGamePhase)].number)
mLayers->stackLayer()->AddNextGamePhase();
else
nextGamePhase();
options[Options::optionInterrupt(currentGamePhase)].number)
{
executeNextPhaseImmediately = false;
}
if (executeNextPhaseImmediately)
{
nextGamePhase();
}
else
{
mLayers->stackLayer()->AddNextGamePhase();
}
}
int GameObserver::forceShuffleLibraries(){
@@ -280,15 +295,26 @@ void GameObserver::Update(float dt){
Player * player = currentPlayer;
if (Constants::MTG_PHASE_COMBATBLOCKERS == currentGamePhase && BLOCKERS == combatStep)
player = player->opponent();
currentActionPlayer = player;
if (isInterrupting) player = isInterrupting;
mLayers->Update(dt,player);
while (mLayers->actionLayer()->stuffHappened){
mLayers->actionLayer()->Update(0);
}
stateEffects();
oldGamePhase = currentGamePhase;
if (combatStep == TRIGGERS)
{
if (!mLayers->stackLayer()->getNext(NULL,0,NOT_RESOLVED))
{
mLayers->stackLayer()->AddNextCombatStep();
}
}
//Auto skip Phases
int skipLevel = (player->playMode == Player::MODE_TEST_SUITE) ? Constants::ASKIP_NONE :
options[Options::ASPHASES].number;
@@ -331,7 +357,7 @@ void GameObserver::stateEffects()
card->afterDamage();
//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);
}
}
+12 -4
View File
@@ -133,7 +133,10 @@ bool GuiCombat::clickOK(){
cursor_pos = NONE;
switch (step)
{
case BLOCKERS : assert(false); return false; // that should not happen
case BLOCKERS :
case TRIGGERS :
assert(false); return false; // that should not happen
case ORDER : go->nextGamePhase(); return true;
case FIRST_STRIKE : return false;
case DAMAGE : validateDamage(); return true;
@@ -441,9 +444,14 @@ int GuiCombat::receiveEventMinus(WEvent* e)
else if (WEventCombatStepChange* event = dynamic_cast<WEventCombatStepChange*>(e))
switch (event->step)
{
case BLOCKERS:
break;
case ORDER:
case BLOCKERS:
break;
case TRIGGERS:
step = TRIGGERS;
return 1;
case ORDER:
{
if (ORDER == step) return 0; // Why do I take this twice ? >.>
if (!go->currentPlayer->displayStack()) { go->nextCombatStep(); return 1; }
+324 -15
View File
@@ -153,7 +153,133 @@ TriggeredAbility * AbilityFactory::parseTrigger(string magicText, int id, Spell
TargetChooser *tc = tcf.createTargetChooser(starget,card);
tc->targetter = NULL;
return NEW TrCardTapped(id,card,tc);
return NEW TrCardTapped(id,card,tc,true);
}
//Card unTapped
found = s.find("untapping(");
if (found != string::npos){
size_t end = s.find (")");
string starget = s.substr(found+10,end - found - 10);
TargetChooserFactory tcf;
TargetChooser *tc = tcf.createTargetChooser(starget,card);
tc->targetter = NULL;
return NEW TrCardTapped(id,card,tc,false);
}
//Card Tapped for mana
found = s.find("tappedformana(");
if (found != string::npos){
size_t end = s.find (")");
string starget = s.substr(found+14,end - found - 14);
TargetChooserFactory tcf;
TargetChooser *tc = tcf.createTargetChooser(starget,card);
tc->targetter = NULL;
return NEW TrCardTappedformana(id,card,tc,true);
}
//Card is attacking
found = s.find("attacking(");
if (found != string::npos){
size_t end = s.find (")");
string starget = s.substr(found+10,end - found - 10);
TargetChooserFactory tcf;
TargetChooser *tc = tcf.createTargetChooser(starget,card);
tc->targetter = NULL;
return NEW TrCardAttacked(id,card,tc);
}
//Card card attacked and is not blocked
found = s.find("notblocked(");
if (found != string::npos){
size_t end = s.find (")");
string starget = s.substr(found+11,end - found - 11);
TargetChooserFactory tcf;
TargetChooser *tc = tcf.createTargetChooser(starget,card);
tc->targetter = NULL;
return NEW TrCardAttackedNotBlocked(id,card,tc);
}
//Card card attacked and is blocked
found = s.find("blocked(");
if (found != string::npos){
size_t end = s.find (")");
string starget = s.substr(found+8,end - found - 8);
TargetChooserFactory tcf;
TargetChooser *tc = tcf.createTargetChooser(starget,card);
tc->targetter = NULL;
found = s.find("from(");
TargetChooser *fromTc = NULL;
if (found != string::npos){
end = s.find (")", found);
starget = s.substr(found+5,end - found - 5);
fromTc = tcf.createTargetChooser(starget,card);
fromTc->targetter = NULL;
}
return NEW TrCardAttackedBlocked(id,card,tc,fromTc);
}
//Card card is a blocker
found = s.find("blocking(");
if (found != string::npos){
size_t end = s.find (")");
string starget = s.substr(found+9,end - found - 9);
TargetChooserFactory tcf;
TargetChooser *tc = tcf.createTargetChooser(starget,card);
tc->targetter = NULL;
found = s.find("from(");
TargetChooser *fromTc = NULL;
if (found != string::npos){
end = s.find (")", found);
starget = s.substr(found+5,end - found - 5);
fromTc = tcf.createTargetChooser(starget,card);
fromTc->targetter = NULL;
}
return NEW TrCardBlocked(id,card,tc,fromTc);
}
//Card card is drawn
found = s.find("drawn(");
if (found != string::npos){
size_t end = s.find (")");
string starget = s.substr(found+6,end - found - 6);
TargetChooserFactory tcf;
TargetChooser *tc = tcf.createTargetChooser(starget,card);
tc->targetter = NULL;
return NEW TrcardDrawn(id,card,tc);
}
//Card is sacrificed
found = s.find("sacrificed(");
if (found != string::npos){
size_t end = s.find (")");
string starget = s.substr(found+11,end - found - 11);
TargetChooserFactory tcf;
TargetChooser *tc = tcf.createTargetChooser(starget,card);
tc->targetter = NULL;
return NEW TrCardSacrificed(id,card,tc);
}
//Card is sacrificed
found = s.find("discarded(");
if (found != string::npos){
size_t end = s.find (")");
string starget = s.substr(found+10,end - found - 10);
TargetChooserFactory tcf;
TargetChooser *tc = tcf.createTargetChooser(starget,card);
tc->targetter = NULL;
return NEW TrCardDiscarded(id,card,tc);
}
//Card Damaging
@@ -173,7 +299,47 @@ TriggeredAbility * AbilityFactory::parseTrigger(string magicText, int id, Spell
fromTc = tcf.createTargetChooser(starget,card);
fromTc->targetter = NULL;
}
return NEW TrDamaged(id,card,tc,fromTc);
return NEW TrDamaged(id,card,tc,fromTc, 0);
}
//Card Damaging combat
found = s.find("combatdamage(");
if (found != string::npos){
size_t end = s.find (")");
string starget = s.substr(found+13,end - found - 13);
TargetChooserFactory tcf;
TargetChooser *tc = tcf.createTargetChooser(starget,card);
tc->targetter = NULL;
found = s.find("from(");
TargetChooser *fromTc = NULL;
if (found != string::npos){
end = s.find (")", found);
starget = s.substr(found+5,end - found - 5);
fromTc = tcf.createTargetChooser(starget,card);
fromTc->targetter = NULL;
}
return NEW TrDamaged(id,card,tc,fromTc, 1);
}
//Card Damaging non combat
found = s.find("damagenoncombat(");
if (found != string::npos){
size_t end = s.find (")");
string starget = s.substr(found+16,end - found - 16);
TargetChooserFactory tcf;
TargetChooser *tc = tcf.createTargetChooser(starget,card);
tc->targetter = NULL;
found = s.find("from(");
TargetChooser *fromTc = NULL;
if (found != string::npos){
end = s.find (")", found);
starget = s.substr(found+5,end - found - 5);
fromTc = tcf.createTargetChooser(starget,card);
fromTc->targetter = NULL;
}
return NEW TrDamaged(id,card,tc,fromTc, 2);
}
int who = 0;
@@ -320,8 +486,6 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
limit = atoi(sWithoutTc.substr(limit_str+6).c_str());
}
AEquip *ae = dynamic_cast<AEquip*>(a);
if (ae){
ae->cost = cost;
@@ -331,7 +495,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
}
ae->tc = tc;
return ae;
}
}
if (tc) return NEW GenericTargetAbility(id, card, tc, a,cost, doTap,limit,restrictions,dest);
return NEW GenericActivatedAbility(id, card, a,cost,doTap,limit,restrictions,dest);
@@ -339,7 +503,6 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
SAFE_DELETE(cost);
}
//kicker cost
found = s.find("kicker ");
if (found == 0){
@@ -492,7 +655,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
case 1: result = NEW AThisForEach(id, card, _target, td, a); break;
default: result = NULL;
}
if (result) result->oneShot = oneShot;
if (result){ result->oneShot = oneShot;}
return result;
}
return NULL;
@@ -633,6 +796,14 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
return a;
}
//ninjutsu
found = s.find("ninjutsu");
if (found != string::npos){
MTGAbility * a = NEW ANinja(id,card,target);
a->oneShot = 1;
return a;
}
//Fizzle (counterspell...)
found = s.find("fizzle");
if (found != string::npos){
@@ -660,10 +831,17 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
if (star != string::npos) multiplier = NEW WParsedInt(s.substr(star+1),spell,card);
size_t end = s.find(")", found);
int tokenId = atoi(s.substr(found + 6,end - found - 6).c_str());
int who;
size_t opponent = s.find("opponent");
if (opponent != string::npos){
who = 1;
}else{
who = 0;
}
if (tokenId){
MTGCard * safetycard = GameApp::collection->getCardById(tokenId);
if (safetycard){//contenue
ATokenCreator * tok = NEW ATokenCreator(id,card,NULL,tokenId,0, multiplier);
ATokenCreator * tok = NEW ATokenCreator(id,card,NULL,tokenId,0, multiplier,who);
tok->oneShot = 1;
return tok;
}else{
@@ -687,8 +865,14 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
if(!spt.find("XX/XX") || !spt.find("xx/xx")){value = spell->computeXX(card);}
parsePowerToughness(spt,&power, &toughness);
string sabilities = s.substr(end+1);
ATokenCreator * tok = NEW ATokenCreator(id,card,NULL,sname,stypes,power + value,toughness + value,sabilities,0, multiplier);
if(s.find("opponent")){
if (opponent != string::npos){
who = 1;
}else{
who = 0;
}
}
ATokenCreator * tok = NEW ATokenCreator(id,card,NULL,sname,stypes,power + value,toughness + value,sabilities,0, multiplier,who);
tok->oneShot = 1;
return tok;
}
@@ -743,6 +927,25 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
return a;
}
//clone
found = s.find("clone");
if (found != string::npos){
int who;
who = 0;
found = s.find("opponent");
if (found != string::npos){
who = 1;
}
string with;
found = s.find("with(");
if (found != string::npos){
size_t end = s.find (")", found);
with = s.substr(found+5,end - found - 5);
}
MTGAbility * a = NEW AACloner(id,card,target,0,who,with);
a->oneShot = 1;
return a;
}
//Bury, destroy
string destroys[] = {"bury","destroy"};
@@ -757,11 +960,26 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
}
}
//sacrifices and discards
string sacdis[] = {"sacrifice","reject"};
int sacdisTypes[]= {1, 0};
for (int i = 0; i < 2; ++i){
found = s.find(sacdis[i]);
if (found != string::npos){
int sacrifice = sacdisTypes[i];
MTGAbility * a = NEW AASacDis(id,card,target,sacrifice);
a->oneShot = 1;
return a;
}
}
int who = TargetChooser::UNSET;
if (s.find(" controller") != string::npos) who=TargetChooser::CONTROLLER;
if (s.find(" opponent") != string::npos) who=TargetChooser::OPPONENT;
if (s.find(" targetcontroller") != string::npos) who=TargetChooser::TARGET_CONTROLLER;
if (s.find(" owner") != string::npos) who=TargetChooser::OWNER;
found = s.find("ueot");
if (found!= string::npos) forceUEOT = 1;
@@ -798,6 +1016,53 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
}
return ab;
}
//PreventCombat Damage
found = s.find("preventalldamage");
if (found != string::npos){
string to = "";
string from = "";
found = s.find("to(");
if (found != string::npos){
size_t end = s.find (")", found);
to = s.substr(found+3,end - found - 3);
}
found = s.find("from(");
if (found != string::npos){
size_t end = s.find (")", found);
from = s.substr(found+5,end - found - 5);
}
MTGAbility * ab;
if (forceUEOT){
ab = NEW APreventAllCombatDamageUEOT(id,card,to,from,1);
}else{
ab = NEW APreventAllCombatDamage(id,card,to,from,1);
}
return ab;
}
//PreventCombat Damage
found = s.find("preventallnoncombat");
if (found != string::npos){
string to = "";
string from = "";
found = s.find("to(");
if (found != string::npos){
size_t end = s.find (")", found);
to = s.substr(found+3,end - found - 3);
}
found = s.find("from(");
if (found != string::npos){
size_t end = s.find (")", found);
from = s.substr(found+5,end - found - 5);
}
MTGAbility * ab;
if (forceUEOT){
ab = NEW APreventAllCombatDamageUEOT(id,card,to,from,2);
}else{
ab = NEW APreventAllCombatDamage(id,card,to,from,2);
}
return ab;
}
//PreventCombat Damage
found = s.find("fog");
@@ -838,6 +1103,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
a->oneShot = 1;
return a;
}
//remove poison
found = s.find("removepoison:");
if (found != string::npos){
@@ -1048,11 +1314,29 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
if (parsePowerToughness(spt,&power, &toughness)){
int MaxOpponent = atoi(s.substr(end+1,end+2).c_str());
return NEW ARampageAbility(id,card,power,toughness,MaxOpponent);
}
return NULL;
}
// the following is NOT dead code. this is for stacking flanking. except auras do not yet support
//giving creatures activated/MTGAbility keywords. soon as i add this support this will be uncommented for stacking flanking.
// //flanking
// found = s.find("flanking");
// if (found != string::npos){
// return NEW AFlankerAbility(id,card);
//}
//bushido
found = s.find("bushido(");
if (found != string::npos){
int end = s.find(")", found);
string spt = s.substr(8,end - 1);
int power, toughness;
if (parsePowerToughness(spt,&power, &toughness)){
return NEW ABushidoAbility(id,card,power,toughness);
}
return NULL;
}
//counter
found = s.find("counter(");
if (found != string::npos){
@@ -1289,6 +1573,14 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
return a;
}
//switch targest power with toughness
found = s.find("twist");
if (found != string::npos){
MTGAbility * a = NEW ATwistUEOT(id,card,target);
a->oneShot = 1;
return a;
}
//Untapper (Ley Druid...)
found = s.find("untap");
if (found != string::npos){
@@ -1331,7 +1623,10 @@ int AbilityFactory::abilityEfficiency(MTGAbility * a, Player * p, int mode, Targ
if (AAsLongAs * abi = dynamic_cast<AAsLongAs *>(a)) return abilityEfficiency(abi->ability,p, mode,tc);
if (AForeach * abi = dynamic_cast<AForeach *>(a)) return abilityEfficiency(abi->ability,p, mode,tc);
if (dynamic_cast<AAFizzler *>(a)) return BAKA_EFFECT_BAD;
if (dynamic_cast<AAUntapper *>(a)) return BAKA_EFFECT_GOOD;
if (dynamic_cast<AADamagePrevent *>(a)) return BAKA_EFFECT_GOOD;
if (dynamic_cast<AACloner *>(a)) return BAKA_EFFECT_GOOD;
if (dynamic_cast<ATwistUEOT *>(a)) return BAKA_EFFECT_BAD;
if (dynamic_cast<AAUntapper *>(a)) return BAKA_EFFECT_GOOD;
if (dynamic_cast<AATapper *>(a)) return BAKA_EFFECT_BAD;
if (AACounter * ac = dynamic_cast<AACounter *>(a)) {
bool negative_effect = ac->power < 0 || ac->toughness < 0;
@@ -1805,7 +2100,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
{
int xCost = computeX(spell,card);
for (int i = 0; i < xCost; i++){
game->opponent()->game->discardRandom(game->opponent()->game->hand);
game->opponent()->game->discardRandom(game->opponent()->game->hand,card);
}
break;
}
@@ -2076,6 +2371,10 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){
game->addObserver(NEW AExalted(_id, card));
}
if (card->basicAbilities[Constants::FLANKING]){
game->addObserver(NEW AFlankerAbility(_id, card));
}
// Tested works the first r10 did not function because of the mistake in the array of the definition
if (card->basicAbilities[Constants::FORESTHOME]){
game->addObserver(NEW AStrongLandLinkCreature(_id, card, "forest"));
@@ -2715,7 +3014,10 @@ AManaProducer::AManaProducer(int id, MTGCardInstance * card, Targetable * t, Man
int result = 0;
if (!mana) mana = game->currentlyActing()->getManaPool();
if (_card == source && (!tap || !source->isTapped()) && game->currentlyActing()->game->inPlay->hasCard(source) && (source->hasType(Subtypes::TYPE_LAND) || !tap || !source->hasSummoningSickness()) ){
if (!cost || mana->canAfford(cost)) result = 1;
if (!cost || mana->canAfford(cost))
{
result = 1;
}
}
return result;
}
@@ -2746,7 +3048,12 @@ AManaProducer::AManaProducer(int id, MTGCardInstance * card, Targetable * t, Man
GameObserver::GetInstance()->currentlyActing()->getManaPool()->pay(cost);
cost->doPayExtra();
}
if (tap) source->tap();
if (tap){
GameObserver *g = GameObserver::GetInstance();
WEvent * e = NEW WEventCardTappedForMana(source, 0, 1);
g->receiveEvent(e);
source->tap();
}
if (options[Options::SFXVOLUME].number > 0){
JSample * sample = resources.RetrieveSample("mana.wav");
@@ -2833,6 +3140,8 @@ AManaProducer::AManaProducer(int id, MTGCardInstance * card, Targetable * t, Man
return source->controller();
case TargetChooser::OPPONENT:
return source->controller()->opponent();
case TargetChooser::OWNER:
return source->owner;
default:
return target;
}
+62 -5
View File
@@ -35,6 +35,7 @@ MTGCardInstance::MTGCardInstance(MTGCard * card, MTGPlayerCards * arg_belongs_to
banding = NULL;
life = toughness;
preventable = 0;
flanked = 0;
}
void MTGCardInstance::copy(MTGCardInstance * card){
@@ -99,6 +100,11 @@ void MTGCardInstance::initMTGCI(){
tapped = 0;
untapping = 0;
frozen = 0;
fresh = 0;
didattacked = 0;
didblocked = 0;
notblocked = 0;
sunburst = NULL;
equipment = NULL;
boughtback = 0;
flashedback = 0;
@@ -106,6 +112,7 @@ void MTGCardInstance::initMTGCI(){
reduxamount = 0;
summoningSickness = 1;
preventable = 0;
flanked = 0;
target = NULL;
type_as_damageable = DAMAGEABLE_MTGCARDINSTANCE;
banding = NULL;
@@ -184,6 +191,10 @@ int MTGCardInstance::afterDamage(){
int MTGCardInstance::bury(){
Player * p = controller();
if (basicAbilities[Constants::EXILEBURY]){
p->game->putInZone(this,p->game->inPlay,owner->game->exile);
return 1;
}
if (!basicAbilities[Constants::INDESTRUCTIBLE]){
p->game->putInZone(this,p->game->inPlay,owner->game->graveyard);
return 1;
@@ -203,6 +214,40 @@ int MTGCardInstance::has(int basicAbility){
return basicAbilities[basicAbility];
}
//sets card as attacked and sends events
void MTGCardInstance::eventattacked(){
didattacked = 1;
WEvent * e = NEW WEventCardAttacked(this);
GameObserver * game = GameObserver::GetInstance();
game->receiveEvent(e);
}
//sets card as attacked and sends events
void MTGCardInstance::eventattackednotblocked(){
didattacked = 1;
WEvent * e = NEW WEventCardAttackedNotBlocked(this);
GameObserver * game = GameObserver::GetInstance();
game->receiveEvent(e);
}
//sets card as attacked and sends events
void MTGCardInstance::eventattackedblocked(){
didattacked = 1;
WEvent * e = NEW WEventCardAttackedBlocked(this);
GameObserver * game = GameObserver::GetInstance();
game->receiveEvent(e);
}
//sets card as blocking and sends events
void MTGCardInstance::eventblocked(){
didblocked = 1;
WEvent * e = NEW WEventCardBlocked(this);
GameObserver * game = GameObserver::GetInstance();
game->receiveEvent(e);
}
//Taps the card
void MTGCardInstance::tap(){
if (tapped) return;
@@ -265,6 +310,8 @@ int MTGCardInstance::initAttackersDefensers(){
banding = NULL;
blockers.clear();
blocked = false;
didattacked = 0;
didblocked = 0;
return 1;
}
@@ -273,7 +320,10 @@ int MTGCardInstance::cleanup(){
initAttackersDefensers();
life=toughness;
GameObserver * game = GameObserver::GetInstance();
if (!game || game->currentPlayer == controller()) summoningSickness = 0;
if (!game || game->currentPlayer == controller())
{
summoningSickness = 0;
}
if (previous && !previous->stillInUse()){
SAFE_DELETE(previous);
}
@@ -471,7 +521,9 @@ int MTGCardInstance::getDefenserRank(MTGCardInstance * blocker){
int MTGCardInstance::removeBlocker(MTGCardInstance * blocker){
blockers.remove(blocker);
if (!blockers.size()) blocked = false;
if (!blockers.size()){
blocked = false;
}
return 1;
}
@@ -537,13 +589,18 @@ int MTGCardInstance::toggleDefenser(MTGCardInstance * opponent){
if (canBlock()){
if (canBlock(opponent)){
setDefenser(opponent);
didblocked = 1;
if(opponent && opponent->controller()->isAI()){
opponent->view->actZ += .8;
opponent->view->actT -= .2;
}
if(!opponent) didblocked = 0;
return 1;
}
}
}
}
return 0;
}
int MTGCardInstance::addProtection(TargetChooser * tc){
tc->targetter = NULL;
protections.push_back(tc);
+5
View File
@@ -96,6 +96,11 @@ int MTGAllCards::processConfLine(string &s, MTGCard *card, CardPrimitive * primi
colors.push_back(j);
}
}
if(colors.size())
{
primitive->setColor(0,1);
primitive->removeColor(0);
}
list<int>::iterator it;
for ( it=colors.begin() ; it != colors.end(); it++ ){
primitive->setColor(*it);
+3
View File
@@ -89,6 +89,9 @@ const char* Constants::MTGBasicAbilities[] = {
"leyline",
"playershroud",
"controllershroud",
"sunburst",
"flanking",
"exiledeath",
};
+4 -1
View File
@@ -249,10 +249,13 @@ MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone
return card; //Error
}
void MTGPlayerCards::discardRandom(MTGGameZone * from){
void MTGPlayerCards::discardRandom(MTGGameZone * from,MTGCardInstance * source){
if (!from->nb_cards)
return;
int r = WRand() % (from->nb_cards);
WEvent * e = NEW WEventCardDiscard(from->cards[r]);
GameObserver * game = GameObserver::GetInstance();
game->receiveEvent(e);
putInZone(from->cards[r],from, graveyard);
}
+124 -2
View File
@@ -49,6 +49,23 @@ int MTGPutInPlayRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
//cost of card.
if (playerMana->canAfford(cost)){
//-------
if(card->has(Constants::SUNBURST)){
for(int i = 1; i != 6;i++)
{
if(player->getManaPool()->hasColor(i)){
if(card->getManaCost()->hasColor(i) > 0){//do nothing if the card already has this color.
}else{
if(card->sunburst < card->getManaCost()->getConvertedCost()){
card->getManaCost()->add(i,1);
card->getManaCost()->remove(0,1);
card->sunburst += 1;
}
}
}
//-------
}
}
return 1;//play if you can afford too.
}
}
@@ -736,6 +753,83 @@ MTGAttackRule * MTGAttackRule::clone() const{
return a;
}
//this rules handles returning cards to combat triggers for activations.
MTGCombatTriggersRule::MTGCombatTriggersRule(int _id):MTGAbility(_id,NULL){
aType=MTGAbility::MTG_COMBATTRIGGERS_RULE;
}
int MTGCombatTriggersRule::receiveEvent(WEvent *e){
if (WEventPhaseChange* event = dynamic_cast<WEventPhaseChange*>(e)) {
if (Constants::MTG_PHASE_COMBATATTACKERS == event->from->id) {
Player * p = game->currentPlayer;
MTGGameZone * z = p->game->inPlay;
for (int i= 0; i < z->nb_cards; i++){
MTGCardInstance * card = z->cards[i];
if (card && card->isAttacker()){
card->eventattacked();
}
}
}
if (Constants::MTG_PHASE_COMBATEND == event->from->id) {
Player * p = game->currentPlayer->opponent();
MTGGameZone * z = p->game->inPlay;
for (int i= 0; i < z->nb_cards; i++){
MTGCardInstance * card = z->cards[i];
if (card){
card->didattacked = 0;
card->didblocked = 0;
card->notblocked = 0;
}
}
}
//---------------
}
if (WEventBlockersChosen * event = dynamic_cast<WEventBlockersChosen*>(e))
{
Player * p = game->currentPlayer;
MTGGameZone * z = p->game->inPlay;
for (int i= 0; i < z->nb_cards; i++){
MTGCardInstance * card = z->cards[i];
if (card && card->isAttacker() && !card->blocked)
{
card->eventattackednotblocked();
card->notblocked += 1;
}
if (card && card->isAttacker() && card->blocked)
{
card->eventattackedblocked();
}
}
MTGGameZone* opponentZone = game->currentPlayer->opponent()->game->inPlay;
for (int i = 0; i < opponentZone->nb_cards; i++)
{
MTGCardInstance* card = opponentZone->cards[i];
if (card && card->didblocked > 0){
card->eventblocked();
}
}
}
return 0;
}
//trigger rules are never distroyed
int MTGCombatTriggersRule::testDestroy(){
return 0;
}
ostream& MTGCombatTriggersRule::toString(ostream& out) const
{
out << "MTGCombatTriggersRule ::: (";
return MTGAbility::toString(out) << ")";
}
MTGCombatTriggersRule * MTGCombatTriggersRule::clone() const{
MTGCombatTriggersRule * a = NEW MTGCombatTriggersRule(*this);
a->isClone = 1;
return a;
}
///------------
OtherAbilitiesEventReceiver::OtherAbilitiesEventReceiver(int _id):MTGAbility(_id,NULL){
}
@@ -773,7 +867,7 @@ MTGBlockRule::MTGBlockRule(int _id):MTGAbility(_id,NULL){
int MTGBlockRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana){
if (currentPhase == Constants::MTG_PHASE_COMBATBLOCKERS && !game->isInterrupting && card->controller() == game->currentlyActing()){
if (card->canBlock()) return 1;
if (card->canBlock())return 1;
}
return 0;
}
@@ -1085,6 +1179,12 @@ int MTGCantCasterstart::receiveEvent(WEvent * event){
WEventZoneChange * e = (WEventZoneChange *) event;
MTGCardInstance * card = e->card->previous;
if(card){
if(e->from == e->card->controller()->game->battlefield && e->to == e->card->controller()->game->graveyard){
e->card->fresh = 1;
}
if(e->to == e->card->controller()->game->battlefield){
e->card->fresh = 1;
}
if (card->basicAbilities[Constants::BOTHCANTCAST] || card->basicAbilities[Constants::BOTHNOCREATURE] || card->basicAbilities[Constants::CANTCAST] || card->basicAbilities[Constants::CANTCASTCREATURE] || card->basicAbilities[Constants::CANTCASTTWO] || card->basicAbilities[Constants::ONLYONEBOTH] || card->basicAbilities[Constants::NOMAXHAND] ){
int ok = 0;
for (int i = 0; i < 2 ; i++){
@@ -1240,8 +1340,30 @@ int MTGSneakAttackRule::receiveEvent(WEvent *e){
MTGGameZone * z = p->game->inPlay;
for (int i= 0; i < z->nb_cards; i++){
MTGCardInstance * card = z->cards[i];
if (card->has(Constants::TREASON)) {p->game->putInGraveyard(card);i--;}
while(card->flanked){//undoes the flanking on a card
card->power += 1;
card->addToToughness(1);
card->flanked -= 1;
}
if (card->has(Constants::TREASON))
{
WEvent * e = NEW WEventCardSacrifice(card);
GameObserver * game = GameObserver::GetInstance();
game->receiveEvent(e);
p->game->putInGraveyard(card);i--;
}
if (card->has(Constants::UNEARTH)) {p->game->putInExile(card);i--;}
if (card->fresh) card->fresh = 0;
if (card->has(Constants::ONLYONEBOTH))
{
card->controller()->castcount = 0;
card->controller()->opponent()->castcount = 0;
}
}
MTGGameZone * f = p->game->graveyard;
for (int k= 0; k < f->nb_cards; k++){
MTGCardInstance * card = f->cards[k];
card->fresh = 0;
}
}
}
+9
View File
@@ -97,10 +97,19 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan
}
break;
case 'd': //DiscardRandom cost
if (value == "d"){
manaCost->addExtraCost(NEW DiscardRandomCost(tc));
}else{
manaCost->addExtraCost(NEW DiscardCost(tc));
}
break;
case 'm': //Mill yourself as a cost
manaCost->addExtraCost(NEW MillCost(tc));
break;
case 'n': //return unblocked attacker cost
TargetChooserFactory tcf;
tc = tcf.createTargetChooser("creature|myBattlefield", c);
manaCost->addExtraCost(NEW Ninja(tc));
break;
case 'c': //Counters
{
+26 -4
View File
@@ -24,6 +24,20 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta
return NEW CardTargetChooser(target,card);
};
found = s.find("opponent");
if (found == 0){
int maxtargets = 1;
Player * opponent = card->controller()->opponent();
return NEW PlayerTargetChooser(card,maxtargets,opponent);
};
found = s.find("controller");
if (found == 0){
int maxtargets = 1;
Player * controller = card->controller();
return NEW PlayerTargetChooser(card,maxtargets,controller);
};
found = s.find("other ");
if (found == 0){
other = true;
@@ -191,26 +205,35 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta
}else{
cd->attacker = 1;
}
}
//Blocker
}else if (attribute.find("blocking") != string::npos){
else if (attribute.find("blocking") != string::npos){
if (minus){
cd->defenser = & MTGCardInstance::NoCard;
}else{
cd->defenser = & MTGCardInstance::AnyCard;
}
}
//Tapped, untapped
}else if (attribute.find("tapped") != string::npos){
else if (attribute.find("tapped") != string::npos){
if (minus){
cd->unsecureSetTapped(-1);
}else{
cd->unsecureSetTapped(1);
}
//Token
}else if (attribute.find("token") != string::npos){
}else if (attribute.find("token") != string::npos){
if (minus){
cd->isToken = -1;
}else{
cd->isToken = 1;
}
//put in its zone this turn
}else if (attribute.find("fresh") != string::npos){
if (minus){
cd->unsecuresetfresh(-1);
}else{
cd->unsecuresetfresh(1);
}
//Power restrictions
}else if (attribute.find("power") != string::npos){
@@ -520,7 +543,6 @@ bool TypeTargetChooser::canTarget(Targetable * target){
MTGCardInstance * card = (MTGCardInstance *) target;
for (int i= 0; i < nbtypes; i++){
if (card->hasSubtype(types[i])) return true;
if (card->has(Constants::CHANGELING)) return true;
if (Subtypes::subtypesList->find(card->getLCName()) == types[i]) return true;
}
return false;
+41
View File
@@ -137,6 +137,28 @@ ThisDescriptor * ThisDescriptorFactory::createThisDescriptor(string s){
return NULL;
}
//whenever this creature attacks do effect
found = s.find("attacking");
if (found != string::npos) {
ThisAttacked * td = NEW ThisAttacked(criterion);
if (td) {
td->comparisonMode = mode;
return td;
}
return NULL;
}
//whenever this creature attacks do effect
found = s.find("notblocked");
if (found != string::npos) {
ThisNotBlocked * td = NEW ThisNotBlocked(criterion);
if (td) {
td->comparisonMode = mode;
return td;
}
return NULL;
}
//controller life
found = s.find("opponentlife");
if (found != string::npos) {
@@ -262,6 +284,25 @@ int ThisEquip::match(MTGCardInstance * card){
return matchValue(card->equipment);
}
ThisAttacked::ThisAttacked(int attack){
comparisonCriterion = attack;
}
int ThisAttacked::match(MTGCardInstance * card){
return matchValue(card->didattacked);
}
ThisNotBlocked::ThisNotBlocked(int unblocked){
comparisonCriterion = unblocked;
}
int ThisNotBlocked::match(MTGCardInstance * card){
return matchValue(card->notblocked);
}
ThisToughness::ThisToughness(int toughness){
comparisonCriterion = toughness;
+66
View File
@@ -18,6 +18,22 @@ WEventPhaseChange::WEventPhaseChange(Phase * from, Phase * to) : WEvent(CHANGE_P
WEventCardTap::WEventCardTap(MTGCardInstance * card, bool before, bool after) : WEventCardUpdate(card), before(before), after(after){}
WEventCardTappedForMana::WEventCardTappedForMana(MTGCardInstance * card, bool before, bool after) : WEventCardUpdate(card), before(before), after(after){}
WEventCardAttacked::WEventCardAttacked(MTGCardInstance * card) : WEventCardUpdate(card){}
WEventCardAttackedNotBlocked::WEventCardAttackedNotBlocked(MTGCardInstance * card) : WEventCardUpdate(card){}
WEventCardAttackedBlocked::WEventCardAttackedBlocked(MTGCardInstance * card) : WEventCardUpdate(card){}
WEventCardBlocked::WEventCardBlocked(MTGCardInstance * card) : WEventCardUpdate(card){}
WEventcardDraw::WEventcardDraw(Player * player,int nb_cards) : player(player), nb_cards(nb_cards){}
WEventCardSacrifice::WEventCardSacrifice(MTGCardInstance * card) : WEventCardUpdate(card){}
WEventCardDiscard::WEventCardDiscard(MTGCardInstance * card) : WEventCardUpdate(card){}
WEventCardChangeType::WEventCardChangeType(MTGCardInstance * card, int type, bool before, bool after) : WEventCardUpdate(card), type(type), before(before), after(after){}
WEventCreatureAttacker::WEventCreatureAttacker(MTGCardInstance * card, Targetable * before, Targetable * after) : WEventCardUpdate(card), before(before), after(after){}
@@ -51,11 +67,61 @@ Targetable * WEventZoneChange::getTarget(int target) {
return NULL;
}
Targetable * WEventCardAttacked::getTarget(int target) {
if (target) return card;
return NULL;
}
Targetable * WEventCardSacrifice::getTarget(int target) {
if (target) return card;
return NULL;
}
Targetable * WEventCardDiscard::getTarget(int target) {
if (target) return card;
return NULL;
}
Targetable * WEventCardAttackedNotBlocked::getTarget(int target) {
if (target) return card;
return NULL;
}
Targetable * WEventCardAttackedBlocked::getTarget(int target) {
switch (target) {
case TARGET_TO :
return card;
case TARGET_FROM :
return card->getNextOpponent();
}
return NULL;
}
Targetable * WEventCardBlocked::getTarget(int target) {
switch (target) {
case TARGET_TO :
return card;
case TARGET_FROM :
return card->getNextOpponent();
}
return NULL;
}
Targetable * WEventCardTap::getTarget(int target){
if (target) return card;
return NULL;
}
Targetable * WEventCardTappedForMana::getTarget(int target){
if (target) return card;
return NULL;
}
Targetable * WEventcardDraw::getTarget(Player * player){
if (player) return player;
return NULL;
}
std::ostream& WEvent::toString(std::ostream& out) const
{
return out << "EVENT";