diff --git a/projects/mtg/Makefile b/projects/mtg/Makefile index 2aaf10bf6..5f60bff1c 100644 --- a/projects/mtg/Makefile +++ b/projects/mtg/Makefile @@ -1,4 +1,4 @@ -OBJS = objs/ActionElement.o objs/ActionLayer.o objs/ActionStack.o objs/AIPlayer.o objs/AIStats.o objs/Blocker.o objs/CardGui.o objs/CardDescriptor.o objs/CardDisplay.o objs/ConstraintResolver.o objs/Counters.o objs/Damage.o objs/DamagerDamaged.o objs/DamageResolverLayer.o objs/DeckDataWrapper.o objs/DeckStats.o objs/DuelLayers.o objs/ExtraCost.o objs/GameApp.o objs/GameLauncher.o objs/GameObserver.o objs/GameOptions.o objs/GameStateDuel.o objs/GameStateMenu.o objs/GameStateOptions.o objs/GameStateShop.o objs/GuiCardsController.o objs/GuiLayers.o objs/Logger.o objs/ManaCost.o objs/ManaCostHybrid.o objs/MenuItem.o objs/MTGAbility.o objs/MTGCardInstance.o objs/MTGCard.o objs/MTGDeck.o objs/MTGDefinitions.o objs/MTGGamePhase.o objs/MTGGameZones.o objs/MTGGuiHand.o objs/MTGGuiPlay.o objs/MTGRules.o objs/OptionItem.o objs/PhaseRing.o objs/Player.o objs/PlayerData.o objs/PlayGuiObjectController.o objs/PlayGuiObject.o objs/PriceList.o objs/ShopItem.o objs/SimpleMenu.o objs/SimpleMenuItem.o objs/Subtypes.o objs/TargetChooser.o objs/TargetsList.o objs/TexturesCache.o objs/Token.o objs/utils.o +OBJS = objs/ActionElement.o objs/ActionLayer.o objs/ActionStack.o objs/AIPlayer.o objs/AIStats.o objs/Blocker.o objs/CardGui.o objs/CardDescriptor.o objs/CardDisplay.o objs/ConstraintResolver.o objs/Counters.o objs/Damage.o objs/DamagerDamaged.o objs/DamageResolverLayer.o objs/DeckDataWrapper.o objs/DeckStats.o objs/DuelLayers.o objs/ExtraCost.o objs/GameApp.o objs/GameLauncher.o objs/GameObserver.o objs/GameOptions.o objs/GameStateDuel.o objs/GameStateMenu.o objs/GameStateOptions.o objs/GameStateShop.o objs/GuiCardsController.o objs/GuiLayers.o objs/Logger.o objs/ManaCost.o objs/ManaCostHybrid.o objs/MenuItem.o objs/MTGAbility.o objs/MTGCardInstance.o objs/MTGCard.o objs/MTGDeck.o objs/MTGDefinitions.o objs/MTGGamePhase.o objs/MTGGameZones.o objs/MTGGuiHand.o objs/MTGGuiPlay.o objs/MTGRules.o objs/OptionItem.o objs/PhaseRing.o objs/Player.o objs/PlayerData.o objs/PlayGuiObjectController.o objs/PlayGuiObject.o objs/PriceList.o objs/ShopItem.o objs/SimpleMenu.o objs/SimpleMenuItem.o objs/Subtypes.o objs/TargetChooser.o objs/TargetsList.o objs/TexturesCache.o objs/Token.o objs/utils.o objs/WEvent.o DEPS = $(patsubst objs/%.o, deps/%.d, $(OBJS)) RESULT = $(shell psp-config --psp-prefix 2> Makefile.cache) diff --git a/projects/mtg/include/ActionElement.h b/projects/mtg/include/ActionElement.h index 8241a2491..cc458eac9 100644 --- a/projects/mtg/include/ActionElement.h +++ b/projects/mtg/include/ActionElement.h @@ -16,6 +16,7 @@ class MTGCardInstance; class Targetable; class TargetChooser; +class WEvent; class ActionElement: public JGuiObject{ protected: @@ -39,6 +40,8 @@ class ActionElement: public JGuiObject{ virtual int isReactingToTargetClick(Targetable * card); virtual int reactToTargetClick(Targetable * card); virtual int isReactingToClick(MTGCardInstance * card){return 0;}; + virtual int stillInUse(MTGCardInstance * card){return 0;}; + virtual int receiveEvent(WEvent * event){return 0;}; virtual int reactToClick(MTGCardInstance * card){return 0;}; virtual const char * getMenuText(){return "Ability";}; }; diff --git a/projects/mtg/include/ActionLayer.h b/projects/mtg/include/ActionLayer.h index 70fd097fe..869897adc 100644 --- a/projects/mtg/include/ActionLayer.h +++ b/projects/mtg/include/ActionLayer.h @@ -13,6 +13,7 @@ class GuiLayer; class Targetable; +class WEvent; class ActionLayer: public GuiLayer, public JGuiListener{ public: @@ -22,12 +23,14 @@ class ActionLayer: public GuiLayer, public JGuiListener{ virtual void Update(float dt); int unstopableRenderInProgress(); bool CheckUserInput(u32 key); - ActionLayer(int id, GameObserver* _game):GuiLayer(id, _game){ menuObject = NULL; abilitiesMenu = NULL;}; + ActionLayer(int id, GameObserver* _game):GuiLayer(id, _game){ menuObject = NULL; abilitiesMenu = NULL;}; int isWaitingForAnswer(); int isReactingToTargetClick(Targetable * card); + int receiveEvent(WEvent * event); int reactToTargetClick(Targetable * card); int isReactingToClick(MTGCardInstance * card); int reactToClick(MTGCardInstance * card); + int stillInUse(MTGCardInstance * card); void setMenuObject(Targetable * object); void ButtonPressed(int controllerid, int controlid); void doReactTo(int menuIndex); diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 54bd296fc..991e5b553 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -10,6 +10,7 @@ #include "CardGui.h" #include "GameOptions.h" #include "Token.h" +#include "WEvent.h" #include #include @@ -169,10 +170,11 @@ public: } for ( it=abilities.begin() ; it != abilities.end(); it++ ){ myToken->basicAbilities[*it] = 1; - } + } + source->controller()->game->stack->addCard(myToken); Spell * spell = NEW Spell(myToken); - source->controller()->game->stack->addCard(myToken); + spell->resolve(); delete spell; return 1; @@ -201,8 +203,9 @@ public: //inplay is a special zone ! for (int i=0; i < 2; i++){ if (destZone == game->players[i]->game->inPlay){ - Spell * spell = NEW Spell(_target); - game->players[i]->game->putInZone(_target, fromZone, game->players[i]->game->stack); + MTGCardInstance * copy = game->players[i]->game->putInZone(_target, fromZone, game->players[i]->game->stack); + Spell * spell = NEW Spell(copy); + spell->resolve(); delete spell; return 1; @@ -1201,9 +1204,9 @@ class AAladdinsLamp: public TargetAbility{ int fireAbility(){ source->tapped = 1; MTGLibrary * library = game->currentlyActing()->game->library; - library->removeCard(tc->getNextCardTarget()); + MTGCardInstance * card = library->removeCard(tc->getNextCardTarget()); library->shuffleTopToBottom(nbcards - 1 ); - library->addCard(tc->getNextCardTarget()); + library->addCard(card); init = 0; return 1; } @@ -1442,41 +1445,39 @@ class AConservator: public MTGAbility{ //Creature bond -class ACreatureBond:public TriggeredAbility{ +class ACreatureBond:public MTGAbility{ public: - int mTriggered; int resolved; - ACreatureBond(int _id, MTGCardInstance * _source, MTGCardInstance * _target):TriggeredAbility(_id,_source,_target){ - mTriggered = 0; + ACreatureBond(int _id, MTGCardInstance * _source, MTGCardInstance * _target):MTGAbility(_id,_source,_target){ resolved = 0; } - int trigger(){ - MTGCardInstance * _target = (MTGCardInstance *) target; - for (int i = 0; i < 2; i++){ - if (!mTriggered && game->players[i]->game->graveyard->hasCard(_target)){ - mTriggered = 1; - return 1; + int receiveEvent(WEvent * event){ + MTGCardInstance * _target = (MTGCardInstance *) target; + if (event->type == WEvent::CHANGE_ZONE){ + WEventZoneChange * e = (WEventZoneChange *) event; + MTGCardInstance * card = e->card->previous; + if (card == _target){ + for (int i = 0; i < 2 ; i++){ + Player * p = game->players[i]; + if (e->to == p->game->graveyard){ + game->mLayers->stackLayer()->addDamage(source,_target->controller(),_target->toughness); + return 1; + } + } } - } + } return 0; - } + } - int resolve(){ - MTGCardInstance * _target = (MTGCardInstance *) target; - game->mLayers->stackLayer()->addDamage(source,_target->controller(),_target->toughness); - resolved = 1; - return 1; - } - - int testDestroy(){ + /* int testDestroy(){ MTGCardInstance * _target = (MTGCardInstance *)target; if(_target->controller()->game->graveyard->hasCard(_target) && !resolved){ return 0; }else{ return TriggeredAbility::testDestroy(); } - } + }*/ }; //1105: Dingus Egg @@ -1733,10 +1734,12 @@ class AAnimateDead:public MTGAbility{ card->life = card->toughness; //Put the card in play again, with all its abilities ! //AbilityFactory af; - Spell * spell = NEW Spell(card); + MTGCardInstance * copy = source->controller()->game->putInZone(card, _target->controller()->game->graveyard, source->controller()->game->stack); + Spell * spell = NEW Spell(copy); //af.addAbilities(game->mLayers->actionLayer()->getMaxId(), spell); - source->controller()->game->putInZone(card, _target->controller()->game->graveyard, source->controller()->game->stack); + spell->resolve(); + target = spell->source; delete spell; } @@ -1893,14 +1896,14 @@ class AKudzu: public TargetAbility{ void Update(float dt){ MTGCardInstance * _target = (MTGCardInstance *)target; - if (!_target->tapped){ + if (_target && !_target->tapped){ previouslyTapped = 0; }else if (!previouslyTapped){ #if defined (WIN32) || defined (LINUX) OutputDebugString("Kudzu Strikes !\n"); #endif MTGCardInstance * _target = (MTGCardInstance *)target; - _target->controller()->game->putInGraveyard(_target); + target = _target->controller()->game->putInGraveyard(_target); reactToClick(source); // ???? } TargetAbility::Update(dt); @@ -1922,7 +1925,7 @@ class AKudzu: public TargetAbility{ target = tc->getNextCardTarget(); source->target = (MTGCardInstance *) target; previouslyTapped = 0; - if (source->target->tapped) previouslyTapped = 1; + if (source->target && source->target->tapped) previouslyTapped = 1; return 1; } diff --git a/projects/mtg/include/Counters.h b/projects/mtg/include/Counters.h index f9191638d..7ad40b0fa 100644 --- a/projects/mtg/include/Counters.h +++ b/projects/mtg/include/Counters.h @@ -37,6 +37,7 @@ class Counters{ Counter * hasCounter(const char * _name,int _power = 0, int _toughness = 0); Counter * hasCounter(int _power, int _toughness); Counter * getNext(Counter * previous = NULL); + int init(); }; diff --git a/projects/mtg/include/MTGAbility.h b/projects/mtg/include/MTGAbility.h index aa7f675d1..ed6e87d6b 100644 --- a/projects/mtg/include/MTGAbility.h +++ b/projects/mtg/include/MTGAbility.h @@ -13,6 +13,7 @@ class ManaCost; class MTGGameZone; class Player; class AManaProducer; +class WEvent; #include "ActionElement.h" #include @@ -33,9 +34,10 @@ using std::map; class MTGAbility: public ActionElement{ protected: char menuText[25]; - Damageable * target; + GameObserver * game; public: + Damageable * target; MTGCardInstance * source; MTGAbility(int id, MTGCardInstance * card); MTGAbility(int id, MTGCardInstance * _source, Damageable * _target); @@ -44,8 +46,10 @@ class MTGAbility: public ActionElement{ virtual void Render(){}; virtual int isReactingToClick(MTGCardInstance * card){return 0;}; virtual int reactToClick(MTGCardInstance * card){return 0;}; + virtual int receiveEvent(WEvent * event){return 0;}; virtual void Update(float dt){}; virtual int fireAbility(); + virtual int stillInUse(MTGCardInstance * card){if (card==source) return 1; return 0;}; virtual int resolve(){return 0;}; diff --git a/projects/mtg/include/MTGCardInstance.h b/projects/mtg/include/MTGCardInstance.h index a671f89b9..cc6782503 100644 --- a/projects/mtg/include/MTGCardInstance.h +++ b/projects/mtg/include/MTGCardInstance.h @@ -38,8 +38,12 @@ class MTGCardInstance: public MTGCard, public Damageable, public Targetable { void initMTGCI(); public: bool isToken; + int stillInUse(); + Player * lastController; MTGGameZone * getCurrentZone(); MTGGameZone * previousZone; + MTGCardInstance * previous; + MTGCardInstance * next; int doDamageTest; int summoningSickness; // The recommended method to test for summoning Sickness ! diff --git a/projects/mtg/include/MTGGameZones.h b/projects/mtg/include/MTGGameZones.h index 68ddb8973..26a44ecf4 100644 --- a/projects/mtg/include/MTGGameZones.h +++ b/projects/mtg/include/MTGGameZones.h @@ -15,8 +15,9 @@ class Player; class MTGGameZone { protected: - Player * owner; + public: + Player * owner; //Both cards and cardsMap contain the cards of a zone. The long term objective is to get rid of the array MTGCardInstance * cards[MTG_MAX_PLAYER_CARDS]; map cardsMap; @@ -93,9 +94,9 @@ class MTGPlayerCards { void discardRandom(MTGGameZone * from); void drawFromLibrary(); void showHand(); - void putInGraveyard(MTGCardInstance * card); - void putInZone(MTGCardInstance * card, MTGGameZone * from, MTGGameZone * to); - void putInPlay(MTGCardInstance * card); + MTGCardInstance * putInGraveyard(MTGCardInstance * card); + MTGCardInstance * putInZone(MTGCardInstance * card, MTGGameZone * from, MTGGameZone * to); + MTGCardInstance * putInPlay(MTGCardInstance * card); int isInPlay(MTGCardInstance * card); }; diff --git a/projects/mtg/include/MTGGuiPlay.h b/projects/mtg/include/MTGGuiPlay.h index 69b0e04f5..259f17a7c 100644 --- a/projects/mtg/include/MTGGuiPlay.h +++ b/projects/mtg/include/MTGGuiPlay.h @@ -49,6 +49,7 @@ class MTGGuiPlay: public PlayGuiObjectController { void Update(float dt); bool CheckUserInput(u32 key); virtual void Render(); + void forceUpdateCards(); void updateCards(); }; diff --git a/projects/mtg/include/MTGRules.h b/projects/mtg/include/MTGRules.h index 99971281f..7b0f862b7 100644 --- a/projects/mtg/include/MTGRules.h +++ b/projects/mtg/include/MTGRules.h @@ -6,7 +6,7 @@ #include "../include/MTGAbility.h" #include "../include/Counters.h" - +#include "../include/WEvent.h" class MTGPutInPlayRule:public MTGAbility{ public: @@ -39,6 +39,49 @@ class MTGBlockRule:public MTGAbility{ /* Persist Rule */ +class MTGPersistRule:public MTGAbility{ + public: + MTGPersistRule(int _id):MTGAbility(_id,NULL){}; + + int receiveEvent(WEvent * event){ +OutputDebugString("Receive1\n"); + if (event->type == WEvent::CHANGE_ZONE){ +OutputDebugString("Receive2\n"); + WEventZoneChange * e = (WEventZoneChange *) event; + MTGCardInstance * card = e->card->previous; + if (card && card->basicAbilities[Constants::PERSIST] && !card->counters->hasCounter(-1,-1)){ +OutputDebugString("Receive3\n"); + int ok = 0; + for (int i = 0; i < 2 ; i++){ + Player * p = game->players[i]; + if (e->from == p->game->inPlay) ok = 1; + } + if (!ok) return 0; +OutputDebugString("Receive4\n"); + for (int i = 0; i < 2 ; i++){ + Player * p = game->players[i]; + if (e->to == p->game->graveyard){ +OutputDebugString("Receive5\n"); + //p->game->putInZone(card, p->game->graveyard, card->owner->game->hand); + MTGCardInstance * copy = p->game->putInZone(e->card, p->game->graveyard, e->card->owner->game->stack); + Spell * spell = NEW Spell(copy); + spell->resolve(); + spell->source->counters->addCounter(-1,-1); + game->mLayers->playLayer()->forceUpdateCards(); + delete spell; + return 1; + } + } + } + } + return 0; + } + + int testDestroy(){return 0;} + +}; + +/* class MTGPersistRule:public ListMaintainerAbility{ public: MTGPersistRule(int _id):ListMaintainerAbility(_id){}; @@ -50,23 +93,29 @@ class MTGPersistRule:public ListMaintainerAbility{ MTGCardInstance * card = ((*it).first); Player * p = card->controller(); if (p->game->graveyard->hasCard(card)){ -#if defined (WIN32) || defined (LINUX) - OutputDebugString("persist passed test 1 !\n"); -#endif - p->game->putInZone(card, p->game->graveyard, p->game->hand); - Spell * spell = NEW Spell(card); - p->game->putInZone(card, p->game->hand, p->game->stack); - spell->resolve(); - delete spell; -#if defined (WIN32) || defined (LINUX) - OutputDebugString("persist passed test 2 !\n"); -#endif - card->counters->addCounter(-1,-1); -#if defined (WIN32) || defined (LINUX) - OutputDebugString("persist passed test 3 !\n"); -#endif + p->game->putInZone(card, p->game->graveyard, p->game->hand); + Spell * spell = NEW Spell(card); + p->game->putInZone(card, p->game->hand, p->game->stack); + spell->resolve(); + delete spell; + card->counters->addCounter(-1,-1); } } + + // Dirtiest Code Ever, we remove the counters here + + for (int i = 0; i < 2; i++){ + Player * p = game->players[i]; + MTGGameZone * zones[] = {p->game->graveyard, p->game->hand, p->game->library, p->game->removedFromGame}; + for (int j = 0; j < 5; j++){ + MTGGameZone * zone = zones[j]; + for (int k=0; k < zone->nb_cards; k++){ + zone->cards[k]->counters->init(); + } + } + } + + ListMaintainerAbility::Update(dt); } @@ -87,7 +136,7 @@ class MTGPersistRule:public ListMaintainerAbility{ int testDestroy(){return 0;} }; - +*/ /* * Rule 420.5e (Legend Rule) diff --git a/projects/mtg/include/WEvent.h b/projects/mtg/include/WEvent.h new file mode 100644 index 000000000..96ac4a9a9 --- /dev/null +++ b/projects/mtg/include/WEvent.h @@ -0,0 +1,24 @@ +#ifndef _WEVENT_H_ +#define _WEVENT_H_ + +class MTGCardInstance; +class MTGGameZone; + +class WEvent{ +public: + enum{ + CHANGE_ZONE = 1, + }; + int type; + WEvent(int _type); +}; + +class WEventZoneChange: public WEvent{ +public: + MTGCardInstance * card; + MTGGameZone * from; + MTGGameZone * to; + WEventZoneChange(MTGCardInstance * _card, MTGGameZone * _from, MTGGameZone *_to); +}; + +#endif \ No newline at end of file diff --git a/projects/mtg/src/ActionLayer.cpp b/projects/mtg/src/ActionLayer.cpp index 6e283ff04..b17294d2f 100644 --- a/projects/mtg/src/ActionLayer.cpp +++ b/projects/mtg/src/ActionLayer.cpp @@ -2,6 +2,7 @@ #include "../include/ActionLayer.h" #include "../include/GameObserver.h" #include "../include/Targetable.h" +#include "../include/WEvent.h" int ActionLayer::unstopableRenderInProgress(){ @@ -93,6 +94,23 @@ int ActionLayer::isWaitingForAnswer(){ return 0; } +int ActionLayer::stillInUse(MTGCardInstance * card){ + for (int i=0;istillInUse(card)) return 1; + } + return 0; +} + +int ActionLayer::receiveEvent(WEvent * event){ + int result = 0; + for (int i=0;ireceiveEvent(event); + } + return result; +} + int ActionLayer::isReactingToTargetClick(Targetable * card){ int result = 0; diff --git a/projects/mtg/src/ActionStack.cpp b/projects/mtg/src/ActionStack.cpp index 5ccedfbe9..2b22c5a37 100644 --- a/projects/mtg/src/ActionStack.cpp +++ b/projects/mtg/src/ActionStack.cpp @@ -86,7 +86,10 @@ Spell::~Spell(){ int Spell::resolve(){ GameObserver * game = GameObserver::GetInstance(); //TODO Remove target if it's not targettable anymore - source->controller()->game->putInPlay(source); + while (source->next){ + source = source->next; + } + source = source->controller()->game->putInPlay(source); //Play SFX if (GameOptions::GetInstance()->values[OPTIONS_SFXVOLUME].getIntValue() > 0){ diff --git a/projects/mtg/src/Counters.cpp b/projects/mtg/src/Counters.cpp index e54bb64a1..9355a74ab 100644 --- a/projects/mtg/src/Counters.cpp +++ b/projects/mtg/src/Counters.cpp @@ -81,6 +81,16 @@ int Counters::addCounter(int _power, int _toughness){ return addCounter("",_power, _toughness); } +int Counters::init(){ + for (int i = mCount-1; i >= 0; i--){ + while (counters[i]->nb >= 1) { + counters[i]->removed(); + counters[i]->nb--; + } + } + return 1; +} + int Counters::removeCounter(const char * _name,int _power, int _toughness){ for (int i = 0; i < mCount; i++){ if (counters[i]->sameAs(_name, _power,_toughness)){ diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index db7c64949..3109aab66 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -51,8 +51,8 @@ int AbilityFactory::destroyAllInPlay(TargetChooser * tc, int bury){ int AbilityFactory::putInPlayFromZone(MTGCardInstance * card, MTGGameZone * zone, Player * p){ - Spell * spell = NEW Spell(card); - p->game->putInZone(card, zone, p->game->stack); + MTGCardInstance * copy = p->game->putInZone(card, zone, p->game->stack); + Spell * spell = NEW Spell(copy); spell->resolve(); delete spell; return 1; @@ -595,6 +595,7 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){ void AbilityFactory::addAbilities(int _id, Spell * spell){ MTGCardInstance * card = spell->source; + if (spell->cursor==1) card->target = spell->getNextCardTarget(); _id = magicText(_id, spell); int putSourceInGraveyard = 0; //For spells that are not already InstantAbilities; @@ -942,7 +943,9 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){ } case 1143: //Animate Dead { - game->addObserver(NEW AAnimateDead(_id, card, card->target)); + AAnimateDead * a = NEW AAnimateDead(_id, card, card->target); + game->addObserver(a); + card->target = ((MTGCardInstance * )a->target); break; } case 1148 : //Cursed lands @@ -1379,8 +1382,9 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){ case 1367: //Swords to Plowshares { - card->target->controller()->life+= card->target->power; - card->target->controller()->game->inPlay->removeCard(card->target); + Player * p = card->target->controller(); + p->life+= card->target->power; + p->game->putInZone(card->target,p->game->inPlay,card->owner->game->removedFromGame); break; } case 1182: //Terror @@ -1597,7 +1601,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell){ } if (putSourceInGraveyard == 1){ MTGPlayerCards * zones = card->controller()->game; - zones->putInGraveyard(card); + card = zones->putInGraveyard(card); } } diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index 8c74a3771..7cbd736d4 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -22,6 +22,8 @@ MTGCardInstance::MTGCardInstance(MTGCard * card, MTGPlayerCards * _belongs_to): attacker = 0; lifeOrig = life; belongs_to=_belongs_to; + owner = _belongs_to->library->owner; + lastController = owner; initAttackersDefensers(); life=toughness; LOG("==Creating MTGCardInstance Successful=="); @@ -32,6 +34,7 @@ MTGCardInstance::~MTGCardInstance(){ LOG("==Deleting MTGCardInstance=="); SAFE_DELETE(blockers); SAFE_DELETE(counters); + SAFE_DELETE(previous); LOG("==Deleting MTGCardInstance Succesfull=="); } void MTGCardInstance::initMTGCI(){ @@ -53,6 +56,9 @@ void MTGCardInstance::initMTGCI(){ changedZoneRecently = 0; counters = NEW Counters(this); previousZone = NULL; + previous = NULL; + next = NULL; + lastController = NULL; } @@ -164,9 +170,19 @@ int MTGCardInstance::cleanup(){ life=toughness; GameObserver * game = GameObserver::GetInstance(); if (!game || game->currentPlayer == controller()) summoningSickness = 0; + if (previous && !previous->stillInUse()){ + SAFE_DELETE(previous); + } return 1; } +int MTGCardInstance::stillInUse(){ +GameObserver * game = GameObserver::GetInstance(); +if (game->mLayers->actionLayer()->stillInUse(this)) return 1; +if (!previous) return 0; +return previous->stillInUse(); +} + /* Summoning Sickness * 212.3f A creaturefs activated ability with the tap symbol or the untap symbol in its activation cost * canft be played unless the creature has been under its controllerfs control since the start of his or @@ -184,9 +200,9 @@ int MTGCardInstance::hasSummoningSickness(){ int MTGCardInstance::changeController(Player * newController){ Player * originalOwner = controller(); if (originalOwner == newController) return 0; - originalOwner->game->inPlay->removeCard(this); - newController->game->inPlay->addCard(this); - summoningSickness = 1; + MTGCardInstance * copy = originalOwner->game->inPlay->removeCard(this); + newController->game->inPlay->addCard(copy); + //summoningSickness = 1; return 1; } @@ -204,12 +220,12 @@ Player * MTGCardInstance::controller(){ GameObserver * game = GameObserver::GetInstance(); if (!game) return NULL; for (int i = 0; i < 2; i++){ - if (game->players[i]->game->inPlay->hasCard(this)) return game->players[i]; - if (game->players[i]->game->stack->hasCard(this)) return game->players[i]; - if (game->players[i]->game->graveyard->hasCard(this)) return game->players[i]; - if (game->players[i]->game->hand->hasCard(this)) return game->players[i]; + if (game->players[i]->game->inPlay->hasCard(this)) return game->players[i]; + if (game->players[i]->game->stack->hasCard(this)) return game->players[i]; + if (game->players[i]->game->graveyard->hasCard(this)) return game->players[i]; + if (game->players[i]->game->hand->hasCard(this)) return game->players[i]; } - return NULL; + return lastController; } int MTGCardInstance::canAttack(){ diff --git a/projects/mtg/src/MTGGameZones.cpp b/projects/mtg/src/MTGGameZones.cpp index d5d11a7bc..ada2029a2 100644 --- a/projects/mtg/src/MTGGameZones.cpp +++ b/projects/mtg/src/MTGGameZones.cpp @@ -2,6 +2,7 @@ #include "../include/MTGGameZones.h" #include "../include/Player.h" #include "../include/GameOptions.h" +#include "../include/WEvent.h" #if defined (WIN32) || defined (LINUX) #include @@ -69,28 +70,32 @@ void MTGPlayerCards::showHand(){ } -void MTGPlayerCards::putInPlay(MTGCardInstance * card){ - hand->removeCard(card); - stack->removeCard(card); //Which one is it ??? +MTGCardInstance * MTGPlayerCards::putInPlay(MTGCardInstance * card){ + MTGCardInstance * copy = hand->removeCard(card); + if(!copy) copy = stack->removeCard(card); //Which one is it ??? - inPlay->addCard(card); - card->summoningSickness = 1; - card->changedZoneRecently = 1.f; + inPlay->addCard(copy); + copy->summoningSickness = 1; + copy->changedZoneRecently = 1.f; + return copy; } -void MTGPlayerCards::putInGraveyard(MTGCardInstance * card){ +MTGCardInstance * MTGPlayerCards::putInGraveyard(MTGCardInstance * card){ + MTGCardInstance * copy = NULL; if (inPlay->hasCard(card)){ - putInZone(card,inPlay, graveyard); + copy = putInZone(card,inPlay, graveyard); }else if (stack->hasCard(card)){ - putInZone(card,stack, graveyard); + copy = putInZone(card,stack, graveyard); }else{ - putInZone(card,hand, graveyard); + copy = putInZone(card,hand, graveyard); } + return copy; } -void MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone * from, MTGGameZone * to){ - if (from->removeCard(card)){ +MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone * from, MTGGameZone * to){ + MTGCardInstance * copy = NULL; + if (copy = from->removeCard(card)){ if (GameOptions::GetInstance()->values[OPTIONS_SFXVOLUME].getIntValue() > 0){ if (to == graveyard){ @@ -106,14 +111,17 @@ void MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone * from, MTGGa if (to != g->players[0]->game->inPlay && to != g->players[1]->game->inPlay){ //Token leaves play: we destroy it //TODO DELETE Object - return; + return NULL; } } - to->addCard(card); - card->changedZoneRecently = 1.f; - - card->reset(); + to->addCard(copy); + copy->changedZoneRecently = 1.f; + GameObserver *g = GameObserver::GetInstance(); + WEvent * e = NEW WEventZoneChange(copy, from, to); + g->mLayers->actionLayer()->receiveEvent(e); + delete e; + return copy; } } @@ -147,6 +155,9 @@ MTGGameZone::~MTGGameZone(){ } void MTGGameZone::setOwner(Player * player){ + char buf[4096]; + sprintf(buf, "Setting Owner : %p\n", player); +OutputDebugString(buf); for (int i=0; iowner = player; } @@ -160,8 +171,15 @@ MTGCardInstance * MTGGameZone::removeCard(MTGCardInstance * card){ if (cards[i] == card){ cards[i] = cards[nb_cards -1]; nb_cards--; - card->previousZone = this; - return card; + if (card->isToken){ //TODO better than this ? + return card; + } + card->lastController = card->controller(); + MTGCardInstance * copy = NEW MTGCardInstance(card->model,card->owner->game); + copy->previous = card; + card->next = copy; + copy->previousZone = this; + return copy; } } return NULL; @@ -206,7 +224,7 @@ void MTGGameZone::shuffle(){ int r = i + (rand() % (nb_cards-i)); // Random remaining position. MTGCardInstance * temp = cards[i]; cards[i] = cards[r]; cards[r] = temp; } - srand(time(0)); // initialize seed "randomly" TODO :improve + //srand(time(0)); // initialize seed "randomly" TODO :improve } diff --git a/projects/mtg/src/MTGGuiPlay.cpp b/projects/mtg/src/MTGGuiPlay.cpp index 052e31753..9e5247b96 100644 --- a/projects/mtg/src/MTGGuiPlay.cpp +++ b/projects/mtg/src/MTGGuiPlay.cpp @@ -156,26 +156,20 @@ void MTGGuiPlay::setTargettingCardPosition(CardGui * cardg, int player, int play return; } -void MTGGuiPlay::updateCards(){ +void MTGGuiPlay::forceUpdateCards(){ GameObserver * game = GameObserver::GetInstance(); Player * player = game->players[0]; int player0Mode =(game->currentPlayer == player); int nb_cards = player->game->inPlay->nb_cards; - MTGCardInstance * attackers[MAX_ATTACKERS]; - for (int i = 0; i players[1]; - int opponent_cards = opponent ->game->inPlay->nb_cards; - if (mCount - offset != (nb_cards+opponent_cards) || game->currentPlayer != currentPlayer ){ //if the number of cards has changed, then an update occured (is this test engouh ?) resetObjects(); AddPlayersGuiInfo(); offset = mCount; bool hasFocus = player0Mode; + offset = 6; + + Player * opponent = game->players[1]; + int opponent_cards = opponent ->game->inPlay->nb_cards; for (int i = 0;icurrentPlayer; +} + +void MTGGuiPlay::updateCards(){ + GameObserver * game = GameObserver::GetInstance(); + Player * player = game->players[0]; + int player0Mode =(game->currentPlayer == player); + int nb_cards = player->game->inPlay->nb_cards; + MTGCardInstance * attackers[MAX_ATTACKERS]; + for (int i = 0; i players[1]; + int opponent_cards = opponent ->game->inPlay->nb_cards; + if (mCount - offset != (nb_cards+opponent_cards) || game->currentPlayer != currentPlayer ){ //if the number of cards has changed, then an update occured (is this test engouh ?) + forceUpdateCards(); } diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index f8a7c2553..6d9ad26b6 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -51,21 +51,22 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card){ card->getManaCost()->doPayExtra(); ManaCost * spellCost = previousManaPool->Diff(player->getManaPool()); delete previousManaPool; - if (card->hasType("land")){ - Spell * spell = NEW Spell(card); - player->game->putInZone(card, player->game->hand, player->game->stack); + if (card->hasType("land")){ + MTGCardInstance * copy = player->game->putInZone(card, player->game->hand, player->game->stack); + Spell * spell = NEW Spell(copy); spell->resolve(); delete spellCost; delete spell; player->canPutLandsIntoPlay--; }else{ + MTGCardInstance * copy = player->game->putInZone(card, player->game->hand, player->game->stack); if (game->targetChooser){ - game->mLayers->stackLayer()->addSpell(card,game->targetChooser->targets,game->targetChooser->cursor, spellCost); + game->mLayers->stackLayer()->addSpell(copy,game->targetChooser->targets,game->targetChooser->cursor, spellCost); SAFE_DELETE(game->targetChooser); }else{ - game->mLayers->stackLayer()->addSpell(card,NULL,0, spellCost); + game->mLayers->stackLayer()->addSpell(copy,NULL,0, spellCost); } - player->game->putInZone(card, player->game->hand, player->game->stack); + } return 1; diff --git a/projects/mtg/src/TestSuiteAI.cpp b/projects/mtg/src/TestSuiteAI.cpp index b08273ac2..92ca3f18f 100644 --- a/projects/mtg/src/TestSuiteAI.cpp +++ b/projects/mtg/src/TestSuiteAI.cpp @@ -235,11 +235,10 @@ void TestSuite::initGame(){ OutputDebugString(buf); if (card && zone != p->game->library){ if (zone == p->game->inPlay){ - p->game->putInZone(card, p->game->library, p->game->hand); - Spell * spell = NEW Spell(card); - p->game->putInZone(card, p->game->hand, p->game->stack); + MTGCardInstance * copy = p->game->putInZone(card, p->game->library, p->game->stack); + Spell * spell = NEW Spell(copy); spell->resolve(); - if (!summoningSickness) card->summoningSickness = 0; + if (!summoningSickness) p->game->inPlay->cards[k]->summoningSickness = 0; delete spell; }else{ if (!p->game->library->hasCard(card)){ diff --git a/projects/mtg/src/WEvent.cpp b/projects/mtg/src/WEvent.cpp new file mode 100644 index 000000000..e5fe72616 --- /dev/null +++ b/projects/mtg/src/WEvent.cpp @@ -0,0 +1,13 @@ +#include "../include/WEvent.h" +#include "../include/MTGCardInstance.h" +#include "../include/MTGGameZones.h" + +WEvent::WEvent(int _type){ + type=_type; +} + +WEventZoneChange::WEventZoneChange(MTGCardInstance * _card, MTGGameZone * _from, MTGGameZone *_to):WEvent(CHANGE_ZONE){ + card = _card; + from = _from; + to = _to; +} \ No newline at end of file diff --git a/projects/mtg/template.vcproj b/projects/mtg/template.vcproj index 3ab367c0d..b6942707e 100644 --- a/projects/mtg/template.vcproj +++ b/projects/mtg/template.vcproj @@ -488,6 +488,10 @@ RelativePath=".\src\utils.cpp" > + + + +