Erwan
- Added WEvent class, allows to send events to abilities - Cards that change zones now becomes new objects (as specified in the Comprehensive rules). This should allow to fix lots of stupid bugs in the near future, but probably brings loads of new issues :(
This commit is contained in:
@@ -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;i<mCount;i++){
|
||||
ActionElement * currentAction = (ActionElement *)mObjects[i];
|
||||
if(currentAction->stillInUse(card)) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ActionLayer::receiveEvent(WEvent * event){
|
||||
int result = 0;
|
||||
for (int i=0;i<mCount;i++){
|
||||
ActionElement * currentAction = (ActionElement *)mObjects[i];
|
||||
result += currentAction->receiveEvent(event);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int ActionLayer::isReactingToTargetClick(Targetable * card){
|
||||
int result = 0;
|
||||
|
||||
|
||||
@@ -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){
|
||||
|
||||
@@ -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)){
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 creature�fs activated ability with the tap symbol or the untap symbol in its activation cost
|
||||
* can�ft be played unless the creature has been under its controller�fs 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(){
|
||||
|
||||
@@ -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 <time.h>
|
||||
@@ -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; i<nb_cards; i++) {
|
||||
cards[i]->owner = 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
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 <MAX_ATTACKERS; i++){
|
||||
attackers[i] = NULL;
|
||||
}
|
||||
|
||||
offset = 6;
|
||||
|
||||
Player * opponent = game->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;i<nb_cards; i++){
|
||||
if (hasFocus) mCurr = mCount ;
|
||||
@@ -192,6 +186,24 @@ void MTGGuiPlay::updateCards(){
|
||||
}
|
||||
|
||||
currentPlayer = game->currentPlayer;
|
||||
}
|
||||
|
||||
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 <MAX_ATTACKERS; i++){
|
||||
attackers[i] = NULL;
|
||||
}
|
||||
|
||||
offset = 6;
|
||||
|
||||
Player * opponent = game->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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)){
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user