From 630a239f315b5b171823254536523577e9c1839b Mon Sep 17 00:00:00 2001 From: "wagic.the.homebrew@gmail.com" Date: Thu, 25 Jun 2009 14:23:21 +0000 Subject: [PATCH] Erwan - tap/untap of a card now sends an event --- projects/mtg/include/AllAbilities.h | 36 ++++++++++++------------- projects/mtg/include/CardDescriptor.h | 1 + projects/mtg/include/MTGCardInstance.h | 10 ++++--- projects/mtg/include/WEvent.h | 11 +++++++- projects/mtg/src/AIPlayer.cpp | 8 +++--- projects/mtg/src/CardDescriptor.cpp | 4 +++ projects/mtg/src/ConstraintResolver.cpp | 2 +- projects/mtg/src/MTGAbility.cpp | 20 +++++++------- projects/mtg/src/MTGCardInstance.cpp | 29 +++++++++++++++----- projects/mtg/src/MTGGameZones.cpp | 2 +- projects/mtg/src/MTGGuiPlay.cpp | 21 +++++++-------- projects/mtg/src/MTGRules.cpp | 2 +- projects/mtg/src/TargetChooser.cpp | 4 +-- projects/mtg/src/WEvent.cpp | 7 +++++ 14 files changed, 97 insertions(+), 60 deletions(-) diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index faddebaa0..91390fab2 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -700,7 +700,7 @@ class AUnBlocker:public MTGAbility{ int reactToClick(MTGCardInstance * _card){ if (!isReactingToClick( _card)) return 0; game->currentlyActing()->getManaPool()->pay(cost); - _card->untap(); + _card->attemptUntap(); return 1; } @@ -1090,7 +1090,7 @@ class ARegularLifeModifierAura:public MTGAbility{ void Update(float dt){ if (newPhase !=currentPhase && newPhase==phase && game->currentPlayer==((MTGCardInstance *)target)->controller()){ - if (!onlyIfTargetTapped || ((MTGCardInstance *)target)->tapped){ + if (!onlyIfTargetTapped || ((MTGCardInstance *)target)->isTapped()){ if (life > 0){ game->currentPlayer->life+=life; }else{ @@ -1432,7 +1432,7 @@ class ATapper:public TargetAbility{ int resolve(){ MTGCardInstance * _target = tc->getNextCardTarget(); if (_target){ - _target->tapped = true; + _target->tap(); } return 1; } @@ -1458,7 +1458,7 @@ class AUntaper:public TargetAbility{ int resolve(){ MTGCardInstance * _target = tc->getNextCardTarget(); if (_target){ - _target->tapped = 0; + _target->untap(); } return 1; } @@ -1539,7 +1539,7 @@ class AStrongLandLinkCreature: public MTGAbility{ if (source->isAttacker()){ if (!game->opponent()->game->inPlay->hasType(land)){ source->attacker=0; - source->tapped = 0; + source->untap(); //TODO Improve, there can be race conditions here } } @@ -1702,7 +1702,7 @@ class AAladdinsLamp: public TargetAbility{ int fireAbility(){ - source->tapped = 1; + source->tap(); MTGLibrary * library = game->currentlyActing()->game->library; MTGCardInstance * card = library->removeCard(tc->getNextCardTarget()); library->shuffleTopToBottom(nbcards - 1 ); @@ -1879,7 +1879,7 @@ class AClockworkBeast:public MTGAbility{ game->currentlyActing()->getManaPool()->pay(& cost); counters ++; ((MTGCardInstance *)target)->power++; - ((MTGCardInstance *)target)->tapped = 1; + ((MTGCardInstance *)target)->tap(); return 1; } @@ -1951,7 +1951,7 @@ class AConservator: public MTGAbility{ int reactToClick(MTGCardInstance * _card){ if (!isReactingToClick( _card)) return 0; game->currentlyActing()->getManaPool()->pay(& cost); - source->tapped = 1; + source->tap(); canprevent = 2; alterDamage(); return 1; @@ -2169,7 +2169,7 @@ class AGlassesOfUrza:public MTGAbility{ int reactToClick(MTGCardInstance * card){ if (!isReactingToClick(card)) return 0; - source->tapped = 1; + source->tap(); isActive = true; return 1; } @@ -2189,7 +2189,7 @@ class AHowlingMine:public MTGAbility{ AHowlingMine(int _id, MTGCardInstance * _source):MTGAbility(_id, _source){} void Update(float dt){ - if (newPhase != currentPhase && newPhase == Constants::MTG_PHASE_DRAW && !source->tapped){ + if (newPhase != currentPhase && newPhase == Constants::MTG_PHASE_DRAW && !source->isTapped()){ game->mLayers->stackLayer()->addDraw(game->currentPlayer); } } @@ -2493,13 +2493,13 @@ class AKudzu: public TargetAbility{ tc->toggleTarget(_target); target = _target; previouslyTapped = 0; - if (_target->tapped) previouslyTapped = 1; + if (_target->isTapped()) previouslyTapped = 1; } void Update(float dt){ MTGCardInstance * _target = (MTGCardInstance *)target; - if (_target && !_target->tapped){ + if (_target && !_target->isTapped()){ previouslyTapped = 0; }else if (!previouslyTapped){ #if defined (WIN32) || defined (LINUX) @@ -2528,7 +2528,7 @@ class AKudzu: public TargetAbility{ target = tc->getNextCardTarget(); source->target = (MTGCardInstance *) target; previouslyTapped = 0; - if (source->target && source->target->tapped) previouslyTapped = 1; + if (source->target && source->target->isTapped()) previouslyTapped = 1; return 1; } @@ -2661,7 +2661,7 @@ class APowerSurge:public TriggeredAbility{ MTGInPlay * inPlay = game->opponent()->game->inPlay; for (int i = 0; i < inPlay->nb_cards; i++){ MTGCardInstance * card = inPlay->cards[i]; - if (!card->tapped && card->hasType("land")){ + if (!card->isTapped() && card->hasType("land")){ totalLands++; } } @@ -2752,7 +2752,7 @@ class APsychicVenom:public MTGAbility{ public: int tapped; APsychicVenom(int _id, MTGCardInstance * _source, MTGCardInstance * _target):MTGAbility(_id, _source,_target){ - tapped = _target->tapped; + tapped = _target->isTapped(); } void Update(float dt){ @@ -3354,7 +3354,7 @@ class AGiveLifeForTappedType:public MTGAbility{ MTGInPlay * inplay = source->controller()->opponent()->game->inPlay; for (int i = 0; i < inplay->nb_cards; i++){ MTGCardInstance * card = inplay->cards[i]; - if (card->tapped && card->hasType(type)) result++; + if (card->isTapped() && card->hasType(type)) result++; } return result; } @@ -3396,7 +3396,7 @@ class AMinionofLeshrac: public TargetAbility{ paidThisTurn = 0; }else if( newPhase == Constants::MTG_PHASE_UPKEEP + 1 && !paidThisTurn){ game->mLayers->stackLayer()->addDamage(source,source->controller(), 5); - source->tapped = 1; + source->tap(); } } TargetAbility::Update(dt); @@ -3551,7 +3551,7 @@ class ASeedbornMuse: public TriggeredAbility{ int resolve(){ for (int j = source->controller()->game->inPlay->nb_cards-1; j >=0 ; j--){ MTGCardInstance * current = source->controller()->game->inPlay->cards[j]; - current->tapped = 0; + current->untap(); } return 1; } diff --git a/projects/mtg/include/CardDescriptor.h b/projects/mtg/include/CardDescriptor.h index 577dad4c1..4ec8143a1 100644 --- a/projects/mtg/include/CardDescriptor.h +++ b/projects/mtg/include/CardDescriptor.h @@ -19,6 +19,7 @@ class CardDescriptor: public MTGCardInstance{ int mode; int init(); CardDescriptor(); + void unsecureSetTapped(int i); void setNegativeSubtype( string value); MTGCardInstance * match(MTGCardInstance * card); MTGCardInstance * match(MTGGameZone * zone); diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index a1903f4e3..5a1205fd6 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -28,6 +28,7 @@ class MTGCardInstance: public MTGCard, public Damageable { int untapping; int nb_damages; string sample; + int tapped; int lifeOrig; Blockers * blockers; @@ -58,14 +59,12 @@ class MTGCardInstance: public MTGCard, public Damageable { int attacker; MTGCardInstance * banding; // If belongs to a band when attacking MTGCardInstance * target; - int tapped; void addType(int type); int canBlock(); int canBlock(MTGCardInstance * opponent); int canAttack(); int afterDamage(); - void setUntapping(); - int isUntapping(); + int has(int ability); int cleanup(); int reset(); @@ -99,9 +98,14 @@ class MTGCardInstance: public MTGCard, public Damageable { int protectedAgainst(MTGCardInstance * card); void copy(MTGCardInstance * card); // in game + + void setUntapping(); + int isUntapping(); int isTapped(); void untap(); void tap(); + void attemptUntap(); + int isInPlay(); void resetAllDamage(); JSample * getSample(); diff --git a/projects/mtg/include/WEvent.h b/projects/mtg/include/WEvent.h index ce3d5804f..4def736c8 100644 --- a/projects/mtg/include/WEvent.h +++ b/projects/mtg/include/WEvent.h @@ -9,12 +9,13 @@ class Phase; class WEvent{ public: enum{ + NOT_SPECIFIED = 0, CHANGE_ZONE = 1, DAMAGE = 2, CHANGE_PHASE = 3, }; int type; - WEvent(int _type); + WEvent(int _type = NOT_SPECIFIED); virtual ~WEvent() {}; }; @@ -41,4 +42,12 @@ public: WEventPhaseChange(Phase * _from, Phase * _to); }; +class WEventCardTap: public WEvent{ +public: + MTGCardInstance * card; + int before; + int after; + WEventCardTap(MTGCardInstance * card, int before, int after); +}; + #endif diff --git a/projects/mtg/src/AIPlayer.cpp b/projects/mtg/src/AIPlayer.cpp index 0c736ce5e..5146bf335 100644 --- a/projects/mtg/src/AIPlayer.cpp +++ b/projects/mtg/src/AIPlayer.cpp @@ -71,7 +71,7 @@ void AIPlayer::tapLandsForMana(ManaCost * potentialMana, ManaCost * cost){ GameObserver * gameObs = GameObserver::GetInstance(); CardDescriptor cd; cd.setColor(Constants::MTG_COLOR_LAND); - cd.tapped = -1; + cd.unsecureSetTapped(-1); MTGCardInstance * card = NULL; while((card = cd.nextmatch(game->inPlay, card))){ @@ -99,7 +99,7 @@ ManaCost * AIPlayer::getPotentialMana(){ potentialMana = NEW ManaCost(); CardDescriptor cd; cd.setColor(Constants::MTG_COLOR_LAND); - cd.tapped = -1; + cd.unsecureSetTapped(-1); MTGCardInstance * card = NULL; while((card = cd.nextmatch(game->inPlay, card))){ @@ -353,7 +353,7 @@ int AIPlayer::getCreaturesInfo(Player * player, int neededInfo , int untapMode, CardDescriptor cd; cd.init(); cd.setType("Creature"); - cd.tapped = untapMode; + cd.unsecureSetTapped(untapMode); MTGCardInstance * card = NULL; while((card = cd.nextmatch(player->game->inPlay, card))){ if (!canAttack || card->canAttack()){ @@ -414,7 +414,7 @@ int AIPlayer::chooseBlockers(){ CardDescriptor cd; cd.init(); cd.setType("Creature"); - cd.tapped = -1; + cd.unsecureSetTapped(-1); MTGCardInstance * card = NULL; GameObserver * g = GameObserver::GetInstance(); MTGAbility * a = g->mLayers->actionLayer()->getAbility(MTGAbility::MTG_BLOCK_RULE); diff --git a/projects/mtg/src/CardDescriptor.cpp b/projects/mtg/src/CardDescriptor.cpp index bed6ad9e2..4a5421c77 100644 --- a/projects/mtg/src/CardDescriptor.cpp +++ b/projects/mtg/src/CardDescriptor.cpp @@ -13,6 +13,10 @@ int CardDescriptor::init(){ return result; } +void CardDescriptor::unsecureSetTapped(int i){ + tapped = i; +} + void CardDescriptor::setNegativeSubtype( string value){ int id = Subtypes::subtypesList->Add(value); addType(-id); diff --git a/projects/mtg/src/ConstraintResolver.cpp b/projects/mtg/src/ConstraintResolver.cpp index 032ce4136..6497e4960 100644 --- a/projects/mtg/src/ConstraintResolver.cpp +++ b/projects/mtg/src/ConstraintResolver.cpp @@ -34,7 +34,7 @@ int ConstraintResolver::untap(GameObserver * game, MTGCardInstance * card){ if (ok) { player->getManaPool()->pay(untapManaCost); - card->untap(); + card->attemptUntap(); } delete untapManaCost; return ok; diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 1713e0006..87bc3045c 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -94,7 +94,7 @@ int AbilityFactory::TapAll(TargetChooser * tc){ for (int j = g->players[i]->game->inPlay->nb_cards-1; j >=0 ; j--){ MTGCardInstance * current = g->players[i]->game->inPlay->cards[j]; if (tc->canTarget(current)){ - current->tapped = 1; + current->tap(); } } } @@ -110,7 +110,7 @@ int AbilityFactory::UntapAll(TargetChooser * tc){ for (int j = g->players[i]->game->inPlay->nb_cards-1; j >=0 ; j--){ MTGCardInstance * current = g->players[i]->game->inPlay->cards[j]; if (tc->canTarget(current)){ - current->tapped = 0; + current->untap(); } } } @@ -390,7 +390,7 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){ if (cost){ game->addObserver(NEW AUntapManaBlocker(id, card, cost)); }else{ - target->tapped = 0; + target->untap(); } } result++; @@ -1011,7 +1011,7 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){ game->addObserver(NEW ATapper(id, card, cost, tc)); } }else{ - target->tapped = 1; + target->tap(); } result++; continue; @@ -1447,7 +1447,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){ MTGInPlay * inplay = player->game->inPlay; for (int i = 0; i < inplay->nb_cards; i++){ MTGCardInstance * current = inplay->cards[i]; - if (current->hasType("land")) current->tapped = 1; + if (current->hasType("land")) current->tap(); } player->getManaPool()->init(); } @@ -1465,7 +1465,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){ { int cost[] = {Constants::MTG_COLOR_ARTIFACT, 4}; game->addObserver(NEW AUntapManaBlocker(_id, card,card->target, NEW ManaCost(cost,1))); - card->target->tapped = 1; + card->target->tap(); break; } case 1172: //Pestilence @@ -1784,7 +1784,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){ } case 1480: //Energy Tap { - card->target->tapped = 1; + card->target->tap(); int mana = card->target->getManaCost()->getConvertedCost(); game->currentlyActing()->getManaPool()->add(Constants::MTG_COLOR_ARTIFACT, mana); } @@ -2360,7 +2360,7 @@ int ActivatedAbility::reactToClick(MTGCardInstance * card){ game->currentlyActing()->getManaPool()->pay(cost); cost->doPayExtra(); } - if (needsTapping) source->tapped = 1; + if (needsTapping) source->tap(); fireAbility(); return 1; @@ -2369,7 +2369,7 @@ int ActivatedAbility::reactToClick(MTGCardInstance * card){ int ActivatedAbility::reactToTargetClick(Targetable * object){ if (!isReactingToTargetClick(object)) return 0; - if (needsTapping) source->tapped = 1; + if (needsTapping) source->tap(); if (cost){ if (object->typeAsTarget() == TARGET_CARD) cost->setExtraCostsAction(this, (MTGCardInstance *) object); OutputDebugString("React To click 2\n"); @@ -2819,7 +2819,7 @@ other solutions need to be provided for abilities that add mana (ex: mana flare) GameObserver::GetInstance()->currentlyActing()->getManaPool()->pay(cost); cost->doPayExtra(); } - if (tap) source->tapped = 1; + if (tap) source->tap(); currentlyTapping++; animation = 1.f; diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index 69577ea2b..031bdc500 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -172,9 +172,24 @@ int MTGCardInstance::has(int basicAbility){ //Taps the card void MTGCardInstance::tap(){ + if (tapped) return; tapped = 1; + WEvent * e = NEW WEventCardTap(this, 0, 1); + GameObserver * game = GameObserver::GetInstance(); + game->receiveEvent(e); + delete e; } +void MTGCardInstance::untap(){ + if (!tapped) return; + tapped = 0; + WEvent * e = NEW WEventCardTap(this, 1, 0); + GameObserver * game = GameObserver::GetInstance(); + game->receiveEvent(e); + delete e; +} + + void MTGCardInstance::setUntapping(){ untapping = 1; } @@ -183,10 +198,10 @@ int MTGCardInstance::isUntapping(){ return untapping; } -//Untaps the card -void MTGCardInstance::untap(){ +//Tries to Untap the card +void MTGCardInstance::attemptUntap(){ if (untapping){ - tapped = 0; + untap(); untapping = 0; } } @@ -210,7 +225,7 @@ int MTGCardInstance::regenerate(){ int MTGCardInstance::triggerRegenerate(){ if (! regenerateTokens) return 0; regenerateTokens--; - tapped = 1; + tap(); life = toughness; initAttackersDefensers(); return 1; @@ -269,7 +284,7 @@ MTGCardInstance * MTGCardInstance::changeController(Player * newController){ //Reset the card parameters int MTGCardInstance::reset(){ cleanup(); - tapped=0; + untap(); SAFE_DELETE(counters); counters = NEW Counters(this); return 1; @@ -383,7 +398,7 @@ int MTGCardInstance::toggleAttacker(){ if (canAttack()){ if (!attacker){ attacker = 1; - tapped = 1; + tap(); return 1; }else{ MTGCardInstance * bandingPartner = getNextPartner(); @@ -394,7 +409,7 @@ int MTGCardInstance::toggleAttacker(){ return 1; }else{ attacker = 0; - tapped = 0; + untap(); return 1; } } diff --git a/projects/mtg/src/MTGGameZones.cpp b/projects/mtg/src/MTGGameZones.cpp index 17aa8fc1f..345f3cbe3 100644 --- a/projects/mtg/src/MTGGameZones.cpp +++ b/projects/mtg/src/MTGGameZones.cpp @@ -372,7 +372,7 @@ void MTGInPlay::untapAll(){ sprintf(buf, "Can untap %s\n", cards[i]->getName()); OutputDebugString(buf); #endif - cards[i]->untap(); + cards[i]->attemptUntap(); } } } diff --git a/projects/mtg/src/MTGGuiPlay.cpp b/projects/mtg/src/MTGGuiPlay.cpp index a901fde78..c9933b637 100644 --- a/projects/mtg/src/MTGGuiPlay.cpp +++ b/projects/mtg/src/MTGGuiPlay.cpp @@ -199,19 +199,16 @@ void MTGGuiPlay::forceUpdateCards(){ } int MTGGuiPlay::receiveEvent(WEvent *event){ - if (event->type == WEvent::CHANGE_ZONE){ - WEventZoneChange * e = dynamic_cast(event); - if (!event) return 0; - int ok = 0; - for (int i = 0; i < 2 ; i++){ - Player * p = game->players[i]; - if (e->from == p->game->inPlay || e->to == p->game->inPlay ) ok = 1; - } - if (!ok) return 0; - forceUpdateCards(); - return 1; + WEventZoneChange * e = dynamic_cast(event); + if (!e) return 0; + int ok = 0; + for (int i = 0; i < 2 ; i++){ + Player * p = game->players[i]; + if (e->from == p->game->inPlay || e->to == p->game->inPlay ) ok = 1; } - return 0; + if (!ok) return 0; + forceUpdateCards(); + return 1; } void MTGGuiPlay::updateCards(){ diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index f2dae0fc3..aea6e62a2 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -110,7 +110,7 @@ void MTGAttackRule::Update(float dt){ int MTGAttackRule::reactToClick(MTGCardInstance * card){ if (!isReactingToClick(card)) return 0; card->attacker = 1; - if (!card->basicAbilities[Constants::VIGILANCE]) card->tapped = 1; + if (!card->basicAbilities[Constants::VIGILANCE]) card->tap(); return 1; } diff --git a/projects/mtg/src/TargetChooser.cpp b/projects/mtg/src/TargetChooser.cpp index a2b8a60b0..8438b3f2d 100644 --- a/projects/mtg/src/TargetChooser.cpp +++ b/projects/mtg/src/TargetChooser.cpp @@ -138,9 +138,9 @@ TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInsta //Tapped, untapped }else if (attribute.find("tapped") != string::npos){ if (minus){ - cd->tapped = -1; + cd->unsecureSetTapped(-1); }else{ - cd->tapped = 1; + cd->unsecureSetTapped(1); } }else{ int attributefound = 0; diff --git a/projects/mtg/src/WEvent.cpp b/projects/mtg/src/WEvent.cpp index 197765665..e667bd61d 100644 --- a/projects/mtg/src/WEvent.cpp +++ b/projects/mtg/src/WEvent.cpp @@ -4,6 +4,7 @@ #include "../include/Damage.h" #include "../include/PhaseRing.h" + WEvent::WEvent(int _type){ type=_type; } @@ -21,4 +22,10 @@ WEventDamage::WEventDamage(Damage *_damage):WEvent(DAMAGE){ WEventPhaseChange::WEventPhaseChange(Phase * _from, Phase * _to):WEvent(CHANGE_PHASE){ from = _from; to = _to; +} + +WEventCardTap::WEventCardTap(MTGCardInstance * _card, int _before, int _after):WEvent(){ + card = _card; + before = _before; + after = _after; } \ No newline at end of file