diff --git a/projects/mtg/include/GameStateDeckViewer.h b/projects/mtg/include/GameStateDeckViewer.h index a4de0eedd..ef6cc1494 100644 --- a/projects/mtg/include/GameStateDeckViewer.h +++ b/projects/mtg/include/GameStateDeckViewer.h @@ -193,7 +193,7 @@ class GameStateDeckViewer: public GameState, public JGuiListener JSoundSystem::GetInstance()->StopMusic(GameApp::music); SAFE_DELETE(GameApp::music); } - GameApp::music = JSoundSystem::GetInstance()->LoadMusic("sound/track1.mp3"); + GameApp::music = GameApp::CommonRes->ssLoadMusic("track1.mp3"); if (GameApp::music){ JSoundSystem::GetInstance()->PlayMusic(GameApp::music, true); } diff --git a/projects/mtg/include/WResourceManager.h b/projects/mtg/include/WResourceManager.h index 0c6686a91..75fa9dab7 100644 --- a/projects/mtg/include/WResourceManager.h +++ b/projects/mtg/include/WResourceManager.h @@ -31,8 +31,11 @@ public: JSample* GetSample(const string &sampleName); JSample* GetSample(int id); - //Wrapped from JRenderer, if we need it. + //Wrapped from other bits, if we want them. JTexture* LoadTexture(const char* filename, int mode = 0, int textureFormat = TEXTURE_FORMAT); + //Wrapped from JSoundSystem + JMusic * ssLoadMusic(const char *fileName); + JSample * ssLoadSample(const char *fileName); //Our new redirect system. string graphicsFile(const string filename, const string specific = ""); diff --git a/projects/mtg/src/Credits.cpp b/projects/mtg/src/Credits.cpp index 04984985d..8cea0e115 100644 --- a/projects/mtg/src/Credits.cpp +++ b/projects/mtg/src/Credits.cpp @@ -103,7 +103,7 @@ void Credits::compute(Player * _p1, Player * _p2, GameApp * _app){ options.save(); } if (unlocked){ - JSample * sample = SampleCache::GetInstance()->getSample("sound/sfx/bonus.wav"); + JSample * sample = SampleCache::GetInstance()->getSample("bonus.wav"); if (sample) JSoundSystem::GetInstance()->PlaySample(sample); } } diff --git a/projects/mtg/src/GameApp.cpp b/projects/mtg/src/GameApp.cpp index 479b46990..51a563840 100644 --- a/projects/mtg/src/GameApp.cpp +++ b/projects/mtg/src/GameApp.cpp @@ -66,12 +66,17 @@ void GameApp::Create() options.theGame = this; //Test for Music files presence - std::ifstream file(RESPATH"/sound/Track0.mp3"); + string filepath = RESPATH; + filepath = filepath + "/" + CommonRes->musicFile("Track0.mp3"); + std::ifstream file(filepath.c_str()); if (file) file.close(); else HasMusic = 0; - std::ifstream file2(RESPATH"/sound/Track1.mp3"); + + filepath = RESPATH; + filepath = filepath + "/" + CommonRes->musicFile("Track1.mp3"); + std::ifstream file2(filepath.c_str()); if (file2) file2.close(); else diff --git a/projects/mtg/src/GameStateMenu.cpp b/projects/mtg/src/GameStateMenu.cpp index 338fec3ab..97015534a 100644 --- a/projects/mtg/src/GameStateMenu.cpp +++ b/projects/mtg/src/GameStateMenu.cpp @@ -150,7 +150,7 @@ void GameStateMenu::Start(){ subMenuController = NULL; if (GameApp::HasMusic && !GameApp::music && options[Options::MUSICVOLUME].number > 0){ - GameApp::music = JSoundSystem::GetInstance()->LoadMusic("sound/Track0.mp3"); + GameApp::music = GameApp::CommonRes->ssLoadMusic("Track0.mp3"); JSoundSystem::GetInstance()->PlayMusic(GameApp::music, true); } diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 9d0c5d015..504b9b0fa 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -2334,7 +2334,7 @@ AManaProducer::AManaProducer(int id, MTGCardInstance * card, ManaCost * _output, if (tap) source->tap(); if (options[Options::SFXVOLUME].number > 0){ - JSample * sample = SampleCache::GetInstance()->getSample("sound/sfx/mana.wav"); + JSample * sample = SampleCache::GetInstance()->getSample("mana.wav"); if (sample) JSoundSystem::GetInstance()->PlaySample(sample); } return resolve(); diff --git a/projects/mtg/src/MTGCardInstance.cpp b/projects/mtg/src/MTGCardInstance.cpp index 8ddd1f376..523350dd4 100644 --- a/projects/mtg/src/MTGCardInstance.cpp +++ b/projects/mtg/src/MTGCardInstance.cpp @@ -1,620 +1,620 @@ -/*--------------------------------------------- - Card Instance - Instance of a given MTGCard in the game - Although there is only one MTGCard of each type, there can be as much Instances of it as needed in the game - -------------------------------------------- -*/ -#include "../include/config.h" -#include "../include/MTGCardInstance.h" -#include "../include/CardDescriptor.h" -#include "../include/Counters.h" -#include "../include/Subtypes.h" -#include -using namespace std; - -MTGCardInstance::MTGCardInstance(): MTGCard(), Damageable(0), view(NULL){ - LOG("==Creating MTGCardInstance=="); - initMTGCI(); - LOG("==Creating MTGCardInstance Successful=="); -} -MTGCardInstance::MTGCardInstance(MTGCard * card, MTGPlayerCards * arg_belongs_to): MTGCard(card), Damageable(card->getToughness()), view(NULL){ - LOG("==Creating MTGCardInstance=="); - initMTGCI(); - model = card; - attacker = 0; - lifeOrig = life; - belongs_to = arg_belongs_to; - owner = NULL; - if (arg_belongs_to) owner = arg_belongs_to->library->owner; - lastController = owner; - defenser = NULL; - banding = NULL; - life = toughness; - LOG("==Creating MTGCardInstance Successful=="); - -} - -void MTGCardInstance::copy(MTGCardInstance * card){ - MTGCard * source = card->model; - for(map::const_iterator it = source->basicAbilities.begin(); it != source->basicAbilities.end(); ++it){ - int i = it->first; - basicAbilities[i] = source->basicAbilities[i]; - } - for (int i = 0; i< MAX_TYPES_PER_CARD; i++){ - types[i] = source->types[i]; - } - nb_types = source->nb_types; - for (int i = 0; i< Constants::MTG_NB_COLORS; i++){ - colors[i] = source->colors[i]; - } - manaCost.copy(source->getManaCost()); - - text = source->text; - name = source->name; - //strcpy(image_name, source->image_name); - - //rarity = source->rarity; - power = source->power; - toughness = source->toughness; - life = toughness; - lifeOrig = life; - //mtgid = source->mtgid; - //setId = source->setId; - magicText = source->magicText; - spellTargetType = source->spellTargetType; - alias = source->alias; - - //Now this is dirty... - int backupid = mtgid; - mtgid = source->getId(); - Spell * spell = NEW Spell(this); - AbilityFactory af; - GameObserver * g = GameObserver::GetInstance(); - af.addAbilities(g->mLayers->actionLayer()->getMaxId(), spell); - delete spell; - mtgid = backupid; -} - -MTGCardInstance::~MTGCardInstance(){ - LOG("==Deleting MTGCardInstance=="); - SAFE_DELETE(untapBlockers); - SAFE_DELETE(counters); - SAFE_DELETE(previous); - LOG("==Deleting MTGCardInstance Succesfull=="); -} -void MTGCardInstance::initMTGCI(){ - sample = ""; - model=NULL; - isToken = false; - lifeOrig = 0; - doDamageTest = 1; - belongs_to=NULL; - tapped = 0; - untapBlockers = NULL; - untapping = 0; - summoningSickness = 0; - target = NULL; - nbprotections = 0; - type_as_damageable = DAMAGEABLE_MTGCARDINSTANCE; - banding = NULL; - owner = NULL; - changedZoneRecently = 0; - counters = NEW Counters(this); - previousZone = NULL; - previous = NULL; - next = NULL; - lastController = NULL; - regenerateTokens = 0; -} - - -const string MTGCardInstance::getDisplayName(){ - return getName(); -} - -void MTGCardInstance::addType(int type){ - types[nb_types] = type; - nb_types++; -} - -UntapBlockers * MTGCardInstance::getUntapBlockers(){ - if (!untapBlockers) untapBlockers = NEW UntapBlockers(); - return untapBlockers; -} - -int MTGCardInstance::isInPlay(){ - GameObserver * game = GameObserver::GetInstance(); - for (int i = 0 ; i < 2 ; i++){ - MTGGameZone * zone = game->players[i]->game->inPlay; - if (zone->hasCard(this)) return 1; - } - return 0; -} - -int MTGCardInstance::afterDamage(){ - if (!doDamageTest) return 0; - doDamageTest = 0; - if (!isCreature()) return 0; - if (life <=0 && isInPlay()){ - return destroy(); - } - return 0; -} - -int MTGCardInstance::bury(){ - Player * p = controller(); - if (!basicAbilities[Constants::INDESTRUCTIBLE]){ - p->game->putInZone(this,p->game->inPlay,owner->game->graveyard); - return 1; - } - return 0; -} -int MTGCardInstance::destroy(){ - if (!triggerRegenerate()) return bury(); - return 0; -} - -MTGGameZone * MTGCardInstance::getCurrentZone(){ - GameObserver * game = GameObserver::GetInstance(); - for (int i = 0; i < 2; i++){ - MTGPlayerCards * g = game->players[i]->game; - MTGGameZone * zones[] = {g->inPlay,g->graveyard,g->hand, g->library}; - for (int k = 0; k < 4; k++){ - MTGGameZone * zone = zones[k]; - if (zone->hasCard(this)) return zone; - } - } - return NULL; -} - -int MTGCardInstance::has(int basicAbility){ - return basicAbilities[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; -} - -int MTGCardInstance::isUntapping(){ - return untapping; -} - -//Tries to Untap the card -void MTGCardInstance::attemptUntap(){ - if (untapping){ - untap(); - untapping = 0; - } -} - -//Tells if the card is tapped or not -int MTGCardInstance::isTapped(){ - return tapped; -} - -void MTGCardInstance::resetAllDamage(){ - //for (int i=0;icurrentPlayer == controller()) summoningSickness = 0; - if (previous && !previous->stillInUse()){ - SAFE_DELETE(previous); - } - regenerateTokens = 0; - 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's activated ability with the tap symbol or the untap symbol in its activation cost - * can't be played unless the creature has been under its controller's control since the start of his or - * her most recent turn. A creature can't attack unless it has been under its controller's control - * since the start of his or her most recent turn. This rule is informally called the "summoning - * sickness" rule. Ignore this rule for creatures with haste (see rule 502.5). - */ -int MTGCardInstance::hasSummoningSickness(){ - if (!summoningSickness) return 0; - if (basicAbilities[Constants::HASTE]) return 0; - if (!isCreature()) return 0; - return 1; -} - -MTGCardInstance * MTGCardInstance::changeController(Player * newController){ - Player * originalOwner = controller(); - if (originalOwner == newController) return 0; - MTGCardInstance * copy = originalOwner->game->putInZone(this, originalOwner->game->inPlay, newController->game->inPlay); - return copy; -} - -//Reset the card parameters -int MTGCardInstance::reset(){ - cleanup(); - untap(); - SAFE_DELETE(counters); - counters = NEW Counters(this); - return 1; -} - - -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->library->hasCard(this)) return game->players[i]; - } - return lastController; -} - -int MTGCardInstance::canAttack(){ - if (tapped) return 0; - if (hasSummoningSickness()) return 0; - if (basicAbilities[Constants::DEFENSER] || basicAbilities[Constants::CANTATTACK]) return 0; - if (!isCreature()) return 0; - if (!isInPlay()) return 0; - return 1; -} - - -int MTGCardInstance::addToToughness(int value){ - toughness+=value; - life+=value; - doDamageTest = 1; - return 1; -} - -int MTGCardInstance::setToughness(int value){ - toughness=value; - life=value; - doDamageTest = 1; - return 1; -} - -int MTGCardInstance::canBlock(){ - if (tapped) return 0; - if (basicAbilities[Constants::CANTBLOCK]) return 0; - if (!isCreature()) return 0; - if (!isInPlay()) return 0; - return 1; -} - -int MTGCardInstance::canBlock(MTGCardInstance * opponent){ - if (!canBlock()) return 0; - if (!opponent) return 1; - if (!opponent->isAttacker()) return 0; - // Comprehensive rule 502.7f : If a creature with protection attacks, it can't be blocked by creatures that have the stated quality. - if (opponent->protectedAgainst(this)) return 0; - if (opponent->basicAbilities[Constants::UNBLOCKABLE]) return 0; - if (opponent->basicAbilities[Constants::FEAR] && !(hasColor(Constants::MTG_COLOR_ARTIFACT) || hasColor(Constants::MTG_COLOR_BLACK))) return 0; - if (opponent->basicAbilities[Constants::FLYING] && !( basicAbilities[Constants::FLYING] || basicAbilities[Constants::REACH])) return 0; - //Can block only creatures with flying if has cloud - if (basicAbilities[Constants::CLOUD] && !( opponent->basicAbilities[Constants::FLYING])) return 0; - // If opponent has shadow and a creature does not have either shadow or reachshadow it cannot be blocked - if (opponent->basicAbilities[Constants::SHADOW] && !( basicAbilities[Constants::SHADOW] || basicAbilities[Constants::REACHSHADOW])) return 0; - // If opponent does not have shadow and a creature has shadow it cannot be blocked - if (!opponent->basicAbilities[Constants::SHADOW] && basicAbilities[Constants::SHADOW]) return 0; - if (opponent->basicAbilities[Constants::SWAMPWALK] && controller()->game->inPlay->hasType("swamp")) return 0; - if (opponent->basicAbilities[Constants::FORESTWALK] && controller()->game->inPlay->hasType("forest")) return 0; - if (opponent->basicAbilities[Constants::ISLANDWALK] && controller()->game->inPlay->hasType("island")) return 0; - if (opponent->basicAbilities[Constants::MOUNTAINWALK] && controller()->game->inPlay->hasType("mountain")) return 0; - if (opponent->basicAbilities[Constants::PLAINSWALK] && controller()->game->inPlay->hasType("plains")) return 0; - return 1; -} - -MTGCardInstance * MTGCardInstance::getNextPartner(){ - MTGInPlay * inplay = controller()->game->inPlay; - MTGCardInstance * bandingPartner = inplay->getNextAttacker(banding); - while (bandingPartner){ - if (basicAbilities[Constants::BANDING] || bandingPartner->basicAbilities[Constants::BANDING]) return bandingPartner; - bandingPartner = inplay->getNextAttacker(bandingPartner); - } - return NULL; -} - -void MTGCardInstance::unband(){ - if (!banding) return; - - MTGCardInstance * _banding = banding; - banding = NULL; - MTGCardInstance * newbanding = NULL; - MTGInPlay * inplay = controller()->game->inPlay; - int nbpartners = inplay->nbPartners(this); - MTGCardInstance * card = inplay->getNextAttacker(NULL); - while(card){ - if (card != this){ - if (card->banding == _banding){ - if (nbpartners == 1){ - card->banding = NULL; - return; - }else{ - if (!newbanding) newbanding = card; - card->banding = newbanding; - } - } - } - card = inplay->getNextAttacker(card); - } - return ; -} - -int MTGCardInstance::setAttacker(int value){ - Targetable * previousTarget = NULL; - Targetable * target = NULL; - Player * p = controller()->opponent(); - if (value) target = p; - if (attacker) previousTarget = p; - attacker = value; - WEvent * e = NEW WEventCreatureAttacker(this,previousTarget, target); - GameObserver::GetInstance()->receiveEvent(e); - //delete e; - return 1; -} - -int MTGCardInstance::toggleAttacker(){ - if (!attacker){ - if (!basicAbilities[Constants::VIGILANCE]) tap(); - setAttacker(1); - return 1; - }else{ - //Banding needs to be debugged... - /*MTGCardInstance * bandingPartner = getNextPartner(); - if (bandingPartner){ - if (banding) unband(); - if (!bandingPartner->banding) bandingPartner->banding = bandingPartner; - banding = bandingPartner->banding; - return 1; - }else{*/ - untap(); - setAttacker(0); - return 1; - //} - } - return 0; -} - -int MTGCardInstance::isAttacker(){ - return attacker; -} - -MTGCardInstance * MTGCardInstance::isDefenser(){ - return defenser; -} - - -int MTGCardInstance::nbOpponents(){ - int result= 0; - MTGCardInstance* opponent = getNextOpponent(); - while (opponent){ - result++; - opponent = getNextOpponent(opponent); - } - return result; -} - -MTGCardInstance * MTGCardInstance::getNextDefenser(MTGCardInstance * previous){ - int found_previous = 0; - if (!previous) found_previous = 1; - list::iterator it; - for (it= blockers.begin(); it != blockers.end(); ++it){ - MTGCardInstance * c = *it; - if (found_previous && c->isInPlay()) return c; - if (c == previous) found_previous = 1; - } - return NULL; -} - -int MTGCardInstance::moveBlockerInRow(MTGCardInstance * blocker){ - list::iterator it1 = find(blockers.begin(), blockers.end(), blocker); - list::iterator it2 = it1; - if (it2 == blockers.end()) it2 = blockers.begin(); else ++it2; - if (it2 == blockers.end()) it2 = blockers.begin(); - - std::iter_swap(it1,it2); - WEvent* e = NEW WEventCreatureBlockerRank(blocker,*it2,this); - GameObserver::GetInstance()->receiveEvent(e); - //delete(e); - return 1; -} - -//Returns opponents to this card for this turn. This * should * take into account banding -MTGCardInstance * MTGCardInstance::getNextOpponent(MTGCardInstance * previous){ - GameObserver * game = GameObserver::GetInstance(); - int foundprevious = 0; - if (!previous) foundprevious = 1; - if (attacker && game->currentPlayer->game->inPlay->hasCard(this)){ - MTGInPlay * inPlay = game->opponent()->game->inPlay; - for (int i = 0; i < inPlay->nb_cards; i ++){ - MTGCardInstance * current = inPlay->cards[i]; - if (current == previous){ - foundprevious = 1; - }else if (foundprevious){ - MTGCardInstance * defensersOpponent = current->isDefenser(); - if (defensersOpponent && (defensersOpponent == this || (banding && defensersOpponent->banding == banding))){ - return current; - } - } - } - }else if (defenser && game->opponent()->game->inPlay->hasCard(this)){ - MTGInPlay * inPlay = game->currentPlayer->game->inPlay; - for (int i = 0; i < inPlay->nb_cards; i ++){ - MTGCardInstance * current = inPlay->cards[i]; - if (current == previous){ - foundprevious = 1; - }else if (foundprevious){ - if (defenser == current || (current->banding && defenser->banding == current->banding)){ - return current; - } - } - } - } - return NULL; -} - -int MTGCardInstance::setDefenser(MTGCardInstance * opponent){ - GameObserver * g = GameObserver::GetInstance(); - if (defenser) { - if (g->players[0]->game->battlefield->hasCard(defenser) || - g->players[1]->game->battlefield->hasCard(defenser) ) { - defenser->blockers.remove(this); - } - } - WEvent * e = NULL; - if (defenser != opponent){ - e = NEW WEventCreatureBlocker(this, defenser, opponent); - - } - defenser = opponent; - if (defenser){ - defenser->blockers.push_back(this); - } - g->blockersSorted = false; - if (e) g->receiveEvent(e); - //delete e; - return 1; -} - -int MTGCardInstance::toggleDefenser(MTGCardInstance * opponent){ - if (canBlock()){ - if (canBlock(opponent)){ - setDefenser(opponent); - return 1; - } - } - return 0; -} - - -int MTGCardInstance::addProtection(CardDescriptor * cd){ - protections[nbprotections] = cd; - nbprotections++; - return nbprotections; -} - -int MTGCardInstance::removeProtection(CardDescriptor * cd, int erase){ - for (int i = 0; i < nbprotections ; i++){ - if (protections[i] == cd){ - if (erase) delete (protections[i]); - protections[i] = protections[nbprotections -1]; - protections[nbprotections -1] = NULL; - nbprotections--; - return 1; - } - } - return 0; -} - -int MTGCardInstance::protectedAgainst(MTGCardInstance * card){ - //Basic protections +/*--------------------------------------------- + Card Instance + Instance of a given MTGCard in the game + Although there is only one MTGCard of each type, there can be as much Instances of it as needed in the game + -------------------------------------------- +*/ +#include "../include/config.h" +#include "../include/MTGCardInstance.h" +#include "../include/CardDescriptor.h" +#include "../include/Counters.h" +#include "../include/Subtypes.h" +#include +using namespace std; + +MTGCardInstance::MTGCardInstance(): MTGCard(), Damageable(0), view(NULL){ + LOG("==Creating MTGCardInstance=="); + initMTGCI(); + LOG("==Creating MTGCardInstance Successful=="); +} +MTGCardInstance::MTGCardInstance(MTGCard * card, MTGPlayerCards * arg_belongs_to): MTGCard(card), Damageable(card->getToughness()), view(NULL){ + LOG("==Creating MTGCardInstance=="); + initMTGCI(); + model = card; + attacker = 0; + lifeOrig = life; + belongs_to = arg_belongs_to; + owner = NULL; + if (arg_belongs_to) owner = arg_belongs_to->library->owner; + lastController = owner; + defenser = NULL; + banding = NULL; + life = toughness; + LOG("==Creating MTGCardInstance Successful=="); + +} + +void MTGCardInstance::copy(MTGCardInstance * card){ + MTGCard * source = card->model; + for(map::const_iterator it = source->basicAbilities.begin(); it != source->basicAbilities.end(); ++it){ + int i = it->first; + basicAbilities[i] = source->basicAbilities[i]; + } + for (int i = 0; i< MAX_TYPES_PER_CARD; i++){ + types[i] = source->types[i]; + } + nb_types = source->nb_types; + for (int i = 0; i< Constants::MTG_NB_COLORS; i++){ + colors[i] = source->colors[i]; + } + manaCost.copy(source->getManaCost()); + + text = source->text; + name = source->name; + //strcpy(image_name, source->image_name); + + //rarity = source->rarity; + power = source->power; + toughness = source->toughness; + life = toughness; + lifeOrig = life; + //mtgid = source->mtgid; + //setId = source->setId; + magicText = source->magicText; + spellTargetType = source->spellTargetType; + alias = source->alias; + + //Now this is dirty... + int backupid = mtgid; + mtgid = source->getId(); + Spell * spell = NEW Spell(this); + AbilityFactory af; + GameObserver * g = GameObserver::GetInstance(); + af.addAbilities(g->mLayers->actionLayer()->getMaxId(), spell); + delete spell; + mtgid = backupid; +} + +MTGCardInstance::~MTGCardInstance(){ + LOG("==Deleting MTGCardInstance=="); + SAFE_DELETE(untapBlockers); + SAFE_DELETE(counters); + SAFE_DELETE(previous); + LOG("==Deleting MTGCardInstance Succesfull=="); +} +void MTGCardInstance::initMTGCI(){ + sample = ""; + model=NULL; + isToken = false; + lifeOrig = 0; + doDamageTest = 1; + belongs_to=NULL; + tapped = 0; + untapBlockers = NULL; + untapping = 0; + summoningSickness = 0; + target = NULL; + nbprotections = 0; + type_as_damageable = DAMAGEABLE_MTGCARDINSTANCE; + banding = NULL; + owner = NULL; + changedZoneRecently = 0; + counters = NEW Counters(this); + previousZone = NULL; + previous = NULL; + next = NULL; + lastController = NULL; + regenerateTokens = 0; +} + + +const string MTGCardInstance::getDisplayName(){ + return getName(); +} + +void MTGCardInstance::addType(int type){ + types[nb_types] = type; + nb_types++; +} + +UntapBlockers * MTGCardInstance::getUntapBlockers(){ + if (!untapBlockers) untapBlockers = NEW UntapBlockers(); + return untapBlockers; +} + +int MTGCardInstance::isInPlay(){ + GameObserver * game = GameObserver::GetInstance(); + for (int i = 0 ; i < 2 ; i++){ + MTGGameZone * zone = game->players[i]->game->inPlay; + if (zone->hasCard(this)) return 1; + } + return 0; +} + +int MTGCardInstance::afterDamage(){ + if (!doDamageTest) return 0; + doDamageTest = 0; + if (!isCreature()) return 0; + if (life <=0 && isInPlay()){ + return destroy(); + } + return 0; +} + +int MTGCardInstance::bury(){ + Player * p = controller(); + if (!basicAbilities[Constants::INDESTRUCTIBLE]){ + p->game->putInZone(this,p->game->inPlay,owner->game->graveyard); + return 1; + } + return 0; +} +int MTGCardInstance::destroy(){ + if (!triggerRegenerate()) return bury(); + return 0; +} + +MTGGameZone * MTGCardInstance::getCurrentZone(){ + GameObserver * game = GameObserver::GetInstance(); + for (int i = 0; i < 2; i++){ + MTGPlayerCards * g = game->players[i]->game; + MTGGameZone * zones[] = {g->inPlay,g->graveyard,g->hand, g->library}; + for (int k = 0; k < 4; k++){ + MTGGameZone * zone = zones[k]; + if (zone->hasCard(this)) return zone; + } + } + return NULL; +} + +int MTGCardInstance::has(int basicAbility){ + return basicAbilities[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; +} + +int MTGCardInstance::isUntapping(){ + return untapping; +} + +//Tries to Untap the card +void MTGCardInstance::attemptUntap(){ + if (untapping){ + untap(); + untapping = 0; + } +} + +//Tells if the card is tapped or not +int MTGCardInstance::isTapped(){ + return tapped; +} + +void MTGCardInstance::resetAllDamage(){ + //for (int i=0;icurrentPlayer == controller()) summoningSickness = 0; + if (previous && !previous->stillInUse()){ + SAFE_DELETE(previous); + } + regenerateTokens = 0; + 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's activated ability with the tap symbol or the untap symbol in its activation cost + * can't be played unless the creature has been under its controller's control since the start of his or + * her most recent turn. A creature can't attack unless it has been under its controller's control + * since the start of his or her most recent turn. This rule is informally called the "summoning + * sickness" rule. Ignore this rule for creatures with haste (see rule 502.5). + */ +int MTGCardInstance::hasSummoningSickness(){ + if (!summoningSickness) return 0; + if (basicAbilities[Constants::HASTE]) return 0; + if (!isCreature()) return 0; + return 1; +} + +MTGCardInstance * MTGCardInstance::changeController(Player * newController){ + Player * originalOwner = controller(); + if (originalOwner == newController) return 0; + MTGCardInstance * copy = originalOwner->game->putInZone(this, originalOwner->game->inPlay, newController->game->inPlay); + return copy; +} + +//Reset the card parameters +int MTGCardInstance::reset(){ + cleanup(); + untap(); + SAFE_DELETE(counters); + counters = NEW Counters(this); + return 1; +} + + +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->library->hasCard(this)) return game->players[i]; + } + return lastController; +} + +int MTGCardInstance::canAttack(){ + if (tapped) return 0; + if (hasSummoningSickness()) return 0; + if (basicAbilities[Constants::DEFENSER] || basicAbilities[Constants::CANTATTACK]) return 0; + if (!isCreature()) return 0; + if (!isInPlay()) return 0; + return 1; +} + + +int MTGCardInstance::addToToughness(int value){ + toughness+=value; + life+=value; + doDamageTest = 1; + return 1; +} + +int MTGCardInstance::setToughness(int value){ + toughness=value; + life=value; + doDamageTest = 1; + return 1; +} + +int MTGCardInstance::canBlock(){ + if (tapped) return 0; + if (basicAbilities[Constants::CANTBLOCK]) return 0; + if (!isCreature()) return 0; + if (!isInPlay()) return 0; + return 1; +} + +int MTGCardInstance::canBlock(MTGCardInstance * opponent){ + if (!canBlock()) return 0; + if (!opponent) return 1; + if (!opponent->isAttacker()) return 0; + // Comprehensive rule 502.7f : If a creature with protection attacks, it can't be blocked by creatures that have the stated quality. + if (opponent->protectedAgainst(this)) return 0; + if (opponent->basicAbilities[Constants::UNBLOCKABLE]) return 0; + if (opponent->basicAbilities[Constants::FEAR] && !(hasColor(Constants::MTG_COLOR_ARTIFACT) || hasColor(Constants::MTG_COLOR_BLACK))) return 0; + if (opponent->basicAbilities[Constants::FLYING] && !( basicAbilities[Constants::FLYING] || basicAbilities[Constants::REACH])) return 0; + //Can block only creatures with flying if has cloud + if (basicAbilities[Constants::CLOUD] && !( opponent->basicAbilities[Constants::FLYING])) return 0; + // If opponent has shadow and a creature does not have either shadow or reachshadow it cannot be blocked + if (opponent->basicAbilities[Constants::SHADOW] && !( basicAbilities[Constants::SHADOW] || basicAbilities[Constants::REACHSHADOW])) return 0; + // If opponent does not have shadow and a creature has shadow it cannot be blocked + if (!opponent->basicAbilities[Constants::SHADOW] && basicAbilities[Constants::SHADOW]) return 0; + if (opponent->basicAbilities[Constants::SWAMPWALK] && controller()->game->inPlay->hasType("swamp")) return 0; + if (opponent->basicAbilities[Constants::FORESTWALK] && controller()->game->inPlay->hasType("forest")) return 0; + if (opponent->basicAbilities[Constants::ISLANDWALK] && controller()->game->inPlay->hasType("island")) return 0; + if (opponent->basicAbilities[Constants::MOUNTAINWALK] && controller()->game->inPlay->hasType("mountain")) return 0; + if (opponent->basicAbilities[Constants::PLAINSWALK] && controller()->game->inPlay->hasType("plains")) return 0; + return 1; +} + +MTGCardInstance * MTGCardInstance::getNextPartner(){ + MTGInPlay * inplay = controller()->game->inPlay; + MTGCardInstance * bandingPartner = inplay->getNextAttacker(banding); + while (bandingPartner){ + if (basicAbilities[Constants::BANDING] || bandingPartner->basicAbilities[Constants::BANDING]) return bandingPartner; + bandingPartner = inplay->getNextAttacker(bandingPartner); + } + return NULL; +} + +void MTGCardInstance::unband(){ + if (!banding) return; + + MTGCardInstance * _banding = banding; + banding = NULL; + MTGCardInstance * newbanding = NULL; + MTGInPlay * inplay = controller()->game->inPlay; + int nbpartners = inplay->nbPartners(this); + MTGCardInstance * card = inplay->getNextAttacker(NULL); + while(card){ + if (card != this){ + if (card->banding == _banding){ + if (nbpartners == 1){ + card->banding = NULL; + return; + }else{ + if (!newbanding) newbanding = card; + card->banding = newbanding; + } + } + } + card = inplay->getNextAttacker(card); + } + return ; +} + +int MTGCardInstance::setAttacker(int value){ + Targetable * previousTarget = NULL; + Targetable * target = NULL; + Player * p = controller()->opponent(); + if (value) target = p; + if (attacker) previousTarget = p; + attacker = value; + WEvent * e = NEW WEventCreatureAttacker(this,previousTarget, target); + GameObserver::GetInstance()->receiveEvent(e); + //delete e; + return 1; +} + +int MTGCardInstance::toggleAttacker(){ + if (!attacker){ + if (!basicAbilities[Constants::VIGILANCE]) tap(); + setAttacker(1); + return 1; + }else{ + //Banding needs to be debugged... + /*MTGCardInstance * bandingPartner = getNextPartner(); + if (bandingPartner){ + if (banding) unband(); + if (!bandingPartner->banding) bandingPartner->banding = bandingPartner; + banding = bandingPartner->banding; + return 1; + }else{*/ + untap(); + setAttacker(0); + return 1; + //} + } + return 0; +} + +int MTGCardInstance::isAttacker(){ + return attacker; +} + +MTGCardInstance * MTGCardInstance::isDefenser(){ + return defenser; +} + + +int MTGCardInstance::nbOpponents(){ + int result= 0; + MTGCardInstance* opponent = getNextOpponent(); + while (opponent){ + result++; + opponent = getNextOpponent(opponent); + } + return result; +} + +MTGCardInstance * MTGCardInstance::getNextDefenser(MTGCardInstance * previous){ + int found_previous = 0; + if (!previous) found_previous = 1; + list::iterator it; + for (it= blockers.begin(); it != blockers.end(); ++it){ + MTGCardInstance * c = *it; + if (found_previous && c->isInPlay()) return c; + if (c == previous) found_previous = 1; + } + return NULL; +} + +int MTGCardInstance::moveBlockerInRow(MTGCardInstance * blocker){ + list::iterator it1 = find(blockers.begin(), blockers.end(), blocker); + list::iterator it2 = it1; + if (it2 == blockers.end()) it2 = blockers.begin(); else ++it2; + if (it2 == blockers.end()) it2 = blockers.begin(); + + std::iter_swap(it1,it2); + WEvent* e = NEW WEventCreatureBlockerRank(blocker,*it2,this); + GameObserver::GetInstance()->receiveEvent(e); + //delete(e); + return 1; +} + +//Returns opponents to this card for this turn. This * should * take into account banding +MTGCardInstance * MTGCardInstance::getNextOpponent(MTGCardInstance * previous){ + GameObserver * game = GameObserver::GetInstance(); + int foundprevious = 0; + if (!previous) foundprevious = 1; + if (attacker && game->currentPlayer->game->inPlay->hasCard(this)){ + MTGInPlay * inPlay = game->opponent()->game->inPlay; + for (int i = 0; i < inPlay->nb_cards; i ++){ + MTGCardInstance * current = inPlay->cards[i]; + if (current == previous){ + foundprevious = 1; + }else if (foundprevious){ + MTGCardInstance * defensersOpponent = current->isDefenser(); + if (defensersOpponent && (defensersOpponent == this || (banding && defensersOpponent->banding == banding))){ + return current; + } + } + } + }else if (defenser && game->opponent()->game->inPlay->hasCard(this)){ + MTGInPlay * inPlay = game->currentPlayer->game->inPlay; + for (int i = 0; i < inPlay->nb_cards; i ++){ + MTGCardInstance * current = inPlay->cards[i]; + if (current == previous){ + foundprevious = 1; + }else if (foundprevious){ + if (defenser == current || (current->banding && defenser->banding == current->banding)){ + return current; + } + } + } + } + return NULL; +} + +int MTGCardInstance::setDefenser(MTGCardInstance * opponent){ + GameObserver * g = GameObserver::GetInstance(); + if (defenser) { + if (g->players[0]->game->battlefield->hasCard(defenser) || + g->players[1]->game->battlefield->hasCard(defenser) ) { + defenser->blockers.remove(this); + } + } + WEvent * e = NULL; + if (defenser != opponent){ + e = NEW WEventCreatureBlocker(this, defenser, opponent); + + } + defenser = opponent; + if (defenser){ + defenser->blockers.push_back(this); + } + g->blockersSorted = false; + if (e) g->receiveEvent(e); + //delete e; + return 1; +} + +int MTGCardInstance::toggleDefenser(MTGCardInstance * opponent){ + if (canBlock()){ + if (canBlock(opponent)){ + setDefenser(opponent); + return 1; + } + } + return 0; +} + + +int MTGCardInstance::addProtection(CardDescriptor * cd){ + protections[nbprotections] = cd; + nbprotections++; + return nbprotections; +} + +int MTGCardInstance::removeProtection(CardDescriptor * cd, int erase){ + for (int i = 0; i < nbprotections ; i++){ + if (protections[i] == cd){ + if (erase) delete (protections[i]); + protections[i] = protections[nbprotections -1]; + protections[nbprotections -1] = NULL; + nbprotections--; + return 1; + } + } + return 0; +} + +int MTGCardInstance::protectedAgainst(MTGCardInstance * card){ + //Basic protections for (int i=Constants::PROTECTIONGREEN; i <= Constants::PROTECTIONWHITE; i++){ if (basicAbilities[i] && card->hasColor( i - Constants::PROTECTIONGREEN + Constants::MTG_COLOR_GREEN )) return 1; - } - - //General protections - for (int i = 0; i < nbprotections ; i++){ - if (protections[i]->match(card)) return 1; - } - return 0; -} - -/* Choose a sound sample to associate to that card */ -JSample * MTGCardInstance::getSample(){ - if (!sample.size()){ - for (int i = nb_types-1; i>0; i--){ - string type = Subtypes::subtypesList->find(types[i]); - type = "sound/sfx/" + type + ".wav"; -#ifdef WIN32 - OutputDebugString(type.c_str()); -#endif - if (fileExists(type.c_str())){ - sample = string(type); - break; - } - } - } - if (!sample.size()){ - for(map::const_iterator it = basicAbilities.begin(); it != basicAbilities.end(); ++it){ - int i = it->first; - if (!basicAbilities[i]) continue; - string type = Constants::MTGBasicAbilities[i]; - type = "sound/sfx/" + type + ".wav"; - if (fileExists(type.c_str())){ - sample = type; - break; - } - } - } - if (!sample.size()){ - string type = Subtypes::subtypesList->find(types[0]); - type = "sound/sfx/" + type + ".wav"; - if (fileExists(type.c_str())){ - sample = type; - } - } - - if (sample.size()) return SampleCache::GetInstance()->getSample(sample); - - return NULL; -} + } + + //General protections + for (int i = 0; i < nbprotections ; i++){ + if (protections[i]->match(card)) return 1; + } + return 0; +} + +/* Choose a sound sample to associate to that card */ +JSample * MTGCardInstance::getSample(){ + if (!sample.size()){ + for (int i = nb_types-1; i>0; i--){ + string type = Subtypes::subtypesList->find(types[i]); + type = type + ".wav"; +#ifdef WIN32 + OutputDebugString(type.c_str()); +#endif + if (fileExists(GameApp::CommonRes->sfxFile(type).c_str())){ + sample = string(type); + break; + } + } + } + if (!sample.size()){ + for(map::const_iterator it = basicAbilities.begin(); it != basicAbilities.end(); ++it){ + int i = it->first; + if (!basicAbilities[i]) continue; + string type = Constants::MTGBasicAbilities[i]; + type = type + ".wav"; + if (fileExists(GameApp::CommonRes->sfxFile(type).c_str())){ + sample = type; + break; + } + } + } + if (!sample.size()){ + string type = Subtypes::subtypesList->find(types[0]); + type = type + ".wav"; + if (fileExists(GameApp::CommonRes->sfxFile(type).c_str())){ + sample = type; + } + } + + if (sample.size()) return SampleCache::GetInstance()->getSample(sample); + + return NULL; +} diff --git a/projects/mtg/src/MTGGameZones.cpp b/projects/mtg/src/MTGGameZones.cpp index 2e9352f99..64eeac66a 100644 --- a/projects/mtg/src/MTGGameZones.cpp +++ b/projects/mtg/src/MTGGameZones.cpp @@ -150,7 +150,7 @@ MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone if (options[Options::SFXVOLUME].number > 0){ if (to == g->players[0]->game->graveyard || to == g->players[1]->game->graveyard){ if (card->isCreature()){ - JSample * sample = SampleCache::GetInstance()->getSample("sound/sfx/graveyard.wav"); + JSample * sample = SampleCache::GetInstance()->getSample("graveyard.wav"); if (sample) JSoundSystem::GetInstance()->PlaySample(sample); } } diff --git a/projects/mtg/src/TexturesCache.cpp b/projects/mtg/src/TexturesCache.cpp index 6a7d336f2..456ad4b52 100644 --- a/projects/mtg/src/TexturesCache.cpp +++ b/projects/mtg/src/TexturesCache.cpp @@ -158,10 +158,10 @@ JSample * SampleCache::getSample(string filename){ map::iterator it = cache.find(filename); if (it == cache.end()){ if (cache.size() >10) cleanOldest(); //Poor man's limit - JSample * sample = JSoundSystem::GetInstance()->LoadSample(filename.c_str()); - if (!sample && fileExists(filename.c_str())){ //Out of Ram ?? + JSample * sample = GameApp::CommonRes->ssLoadSample(filename.c_str()); + if (!sample && fileExists(GameApp::CommonRes->sfxFile(filename).c_str())){ //Out of Ram ?? cleanCache(); - sample = JSoundSystem::GetInstance()->LoadSample(filename.c_str()); + sample = GameApp::CommonRes->ssLoadSample(filename.c_str()); } cache[filename] = NEW SampleCached(lastTime, sample); diff --git a/projects/mtg/src/WResourceManager.cpp b/projects/mtg/src/WResourceManager.cpp index 5321ac7a8..8e326a8b3 100644 --- a/projects/mtg/src/WResourceManager.cpp +++ b/projects/mtg/src/WResourceManager.cpp @@ -206,4 +206,11 @@ JSample* WResourceManager::GetSample(int id){ JTexture* WResourceManager::LoadTexture(const char* filename, int mode, int textureFormat){ return JRenderer::GetInstance()->LoadTexture(graphicsFile(filename).c_str(),mode,textureFormat); +} + +JMusic * WResourceManager::ssLoadMusic(const char *fileName){ + return JSoundSystem::GetInstance()->LoadMusic(musicFile(fileName).c_str()); +} +JSample * WResourceManager::ssLoadSample(const char *fileName){ + return JSoundSystem::GetInstance()->LoadSample(sfxFile(fileName).c_str()); } \ No newline at end of file