Performance improvements/cleanup: card->hasType("foo") performs a string lookup for an integer id. Now that our primitives have over 1000 types (1018, I believe is the number I saw while debugging), this is not the cheapest lookup. Over the course of time, a lot of new rules have crept in the code - support for 'aura', 'equipment', and recently 'planeswalker'. While profiling, I saw an inordinate amount of time being used doing map lookups for these strings. Since they're used so frequently, I've added them to the SubTypes enumeration, and swapped out doing the string lookup in favour of using the int ID directly. I also found a few places where we were using hasType("Creature") or hasType("land") when we already had helper functions to do the int lookup, so I swapped these in as appropriate, as well as a couple of places where we had hasType("instant") instead of hasType(Subtypes::TYPE_INSTANT), etc.

This commit is contained in:
wrenczes@gmail.com
2011-04-10 00:07:34 +00:00
parent 62da8e7ad8
commit 99ed83c5e8
12 changed files with 67 additions and 61 deletions
+4 -3
View File
@@ -15,6 +15,7 @@
#include "WEvent.h" #include "WEvent.h"
#include "GuiStatic.h" #include "GuiStatic.h"
#include "GameObserver.h" #include "GameObserver.h"
#include "Subtypes.h"
#include "ThisDescriptor.h" #include "ThisDescriptor.h"
#include <JGui.h> #include <JGui.h>
#include <hge/hgeparticle.h> #include <hge/hgeparticle.h>
@@ -130,7 +131,7 @@ public:
intValue = 0; intValue = 0;
intValue = target->thatmuch; intValue = target->thatmuch;
int checkagain = 0; int checkagain = 0;
if(target->hasSubtype("aura") || target->hasSubtype("equipment")) if(target->hasSubtype(Subtypes::TYPE_AURA) || target->hasSubtype(Subtypes::TYPE_EQUIPMENT))
{ {
if(target->target) if(target->target)
{ {
@@ -2727,7 +2728,7 @@ public:
{ {
if(card->isPhased || source->isPhased) if(card->isPhased || source->isPhased)
return 0; return 0;
if ((tc->source->hasSubtype("aura") || tc->source->hasSubtype("equipment") || tc->source->hasSubtype("instant") if ((tc->source->hasSubtype(Subtypes::TYPE_AURA) || tc->source->hasSubtype(Subtypes::TYPE_EQUIPMENT) || tc->source->hasSubtype("instant")
|| tc->source->hasSubtype("sorcery")) && tc->canTarget(card) && card == tc->source->target && card != tc->source) return 1; || tc->source->hasSubtype("sorcery")) && tc->canTarget(card) && card == tc->source->target && card != tc->source) return 1;
return 0; return 0;
} }
@@ -2759,7 +2760,7 @@ public:
{ {
MTGAbility * a = ability->clone(); MTGAbility * a = ability->clone();
if (a->source->hasSubtype("aura") || a->source->hasSubtype("equipment") || a->source->hasSubtype("instant") if (a->source->hasSubtype(Subtypes::TYPE_AURA) || a->source->hasSubtype(Subtypes::TYPE_EQUIPMENT) || a->source->hasSubtype("instant")
|| a->source->hasSubtype("sorcery")) || a->source->hasSubtype("sorcery"))
{ {
a->target = a->source->target; a->target = a->source->target;
+4 -2
View File
@@ -19,7 +19,10 @@ public:
TYPE_LAND = 5, TYPE_LAND = 5,
TYPE_ARTIFACT = 6, TYPE_ARTIFACT = 6,
TYPE_LEGENDARY = 7, TYPE_LEGENDARY = 7,
LAST_TYPE = TYPE_LEGENDARY, TYPE_EQUIPMENT = 8,
TYPE_AURA = 9,
TYPE_PLANESWALKER = 10,
LAST_TYPE = TYPE_PLANESWALKER,
}; };
protected: protected:
@@ -28,7 +31,6 @@ protected:
public: public:
static Subtypes * subtypesList; static Subtypes * subtypesList;
Subtypes(); Subtypes();
int find(const char * subtype, bool forceAdd = true);
int find(string subtype, bool forceAdd = true); int find(string subtype, bool forceAdd = true);
string find(unsigned int id); string find(unsigned int id);
}; };
+1 -1
View File
@@ -427,7 +427,7 @@ int AIAction::getEfficiency()
{ {
MTGCardInstance * _target = (MTGCardInstance *) (a->target); MTGCardInstance * _target = (MTGCardInstance *) (a->target);
//nothing huge here, just ensuring that Ai makes his noncreature becomers into creatures during first main, so it can actually use them in combat. //nothing huge here, just ensuring that Ai makes his noncreature becomers into creatures during first main, so it can actually use them in combat.
if (_target && !_target->hasType("Creature") && g->getCurrentGamePhase() == Constants::MTG_PHASE_FIRSTMAIN) if (_target && !_target->isCreature() && g->getCurrentGamePhase() == Constants::MTG_PHASE_FIRSTMAIN)
{ {
efficiency = 100; efficiency = 100;
} }
+2 -1
View File
@@ -11,6 +11,7 @@ The Action Stack contains all information for Game Events that can be interrupte
#include "GameOptions.h" #include "GameOptions.h"
#include "ManaCost.h" #include "ManaCost.h"
#include "MTGAbility.h" #include "MTGAbility.h"
#include "Subtypes.h"
#include "TargetChooser.h" #include "TargetChooser.h"
#include "Translate.h" #include "Translate.h"
#include "WResourceManager.h" #include "WResourceManager.h"
@@ -289,7 +290,7 @@ Spell::~Spell()
int Spell::resolve() int Spell::resolve()
{ {
GameObserver * game = GameObserver::GetInstance(); GameObserver * game = GameObserver::GetInstance();
if (!source->hasType("instant") && !source->hasType("sorcery")) if (!source->hasType(Subtypes::TYPE_INSTANT) && !source->hasType(Subtypes::TYPE_SORCERY))
{ {
Player * p = source->controller(); Player * p = source->controller();
int castMethod = source->castMethod; int castMethod = source->castMethod;
+5 -5
View File
@@ -767,12 +767,12 @@ int AANewTarget::resolve()
MTGCardInstance * refreshed = source->controller()->game->putInZone(_target,_target->currentZone,source->controller()->game->battlefield); MTGCardInstance * refreshed = source->controller()->game->putInZone(_target,_target->currentZone,source->controller()->game->battlefield);
Spell * reUp = NEW Spell(refreshed); Spell * reUp = NEW Spell(refreshed);
if(reUp->source->hasSubtype("aura")) if(reUp->source->hasSubtype(Subtypes::TYPE_AURA))
{ {
reUp->source->target = source; reUp->source->target = source;
reUp->resolve(); reUp->resolve();
} }
if(_target->hasSubtype("equipment")) if(_target->hasSubtype(Subtypes::TYPE_EQUIPMENT))
{ {
reUp->resolve(); reUp->resolve();
GameObserver * g = g->GetInstance(); GameObserver * g = g->GetInstance();
@@ -3189,7 +3189,7 @@ void ABlink::Update(float dt)
} }
Spell * spell = NEW Spell(Blinker); Spell * spell = NEW Spell(Blinker);
spell->source->counters->init(); spell->source->counters->init();
if(spell->source->hasSubtype("aura") && !blinkhand) if(spell->source->hasSubtype(Subtypes::TYPE_AURA) && !blinkhand)
{ {
TargetChooserFactory tcf; TargetChooserFactory tcf;
TargetChooser * tc = tcf.createTargetChooser(spell->source->spellTargetType,spell->source); TargetChooser * tc = tcf.createTargetChooser(spell->source->spellTargetType,spell->source);
@@ -3223,7 +3223,7 @@ void ABlink::Update(float dt)
} }
spell->source->power = spell->source->origpower; spell->source->power = spell->source->origpower;
spell->source->toughness = spell->source->origtoughness; spell->source->toughness = spell->source->origtoughness;
if(!spell->source->hasSubtype("aura")) if(!spell->source->hasSubtype(Subtypes::TYPE_AURA))
{ {
spell->resolve(); spell->resolve();
if(stored) if(stored)
@@ -3288,7 +3288,7 @@ void ABlink::resolveBlink()
} }
Spell * spell = NEW Spell(Blinker); Spell * spell = NEW Spell(Blinker);
spell->source->counters->init(); spell->source->counters->init();
if(spell->source->hasSubtype("aura") && !blinkhand) if(spell->source->hasSubtype(Subtypes::TYPE_AURA) && !blinkhand)
{ {
TargetChooserFactory tcf; TargetChooserFactory tcf;
TargetChooser * tc = tcf.createTargetChooser(spell->source->spellTargetType,spell->source); TargetChooser * tc = tcf.createTargetChooser(spell->source->spellTargetType,spell->source);
+7 -7
View File
@@ -6,6 +6,7 @@
#include "Damage.h" #include "Damage.h"
#include "Rules.h" #include "Rules.h"
#include "ExtraCost.h" #include "ExtraCost.h"
#include "Subtypes.h"
#include <JLogger.h> #include <JLogger.h>
#include <JRenderer.h> #include <JRenderer.h>
@@ -13,7 +14,6 @@ GameObserver * GameObserver::mInstance = NULL;
GameObserver* GameObserver::GetInstance() GameObserver* GameObserver::GetInstance()
{ {
return mInstance; return mInstance;
} }
@@ -296,7 +296,7 @@ void GameObserver::startGame(Rules * rules)
for (int j = 0; j < z->nb_cards; j++) for (int j = 0; j < z->nb_cards; j++)
{ {
MTGCardInstance * _card = z->cards[j]; MTGCardInstance * _card = z->cards[j];
if (_card->hasType("land")) if (_card->isLand())
{ {
card = _card; card = _card;
j = z->nb_cards; j = z->nb_cards;
@@ -403,12 +403,12 @@ void GameObserver::gameStateBasedEffects()
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
//Remove auras that don't have a valid target anymore// //Remove auras that don't have a valid target anymore//
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
if (card->target && !isInPlay(card->target) && !card->hasType("equipment")) if (card->target && !isInPlay(card->target) && !card->hasType(Subtypes::TYPE_EQUIPMENT))
{ {
players[i]->game->putInGraveyard(card); players[i]->game->putInGraveyard(card);
} }
card->enchanted = false; card->enchanted = false;
if (card->target && isInPlay(card->target) && !card->hasType("equipment") && card->hasSubtype("aura")) if (card->target && isInPlay(card->target) && !card->hasType(Subtypes::TYPE_EQUIPMENT) && card->hasSubtype(Subtypes::TYPE_AURA))
{ {
card->target->enchanted = true; card->target->enchanted = true;
} }
@@ -455,7 +455,7 @@ void GameObserver::gameStateBasedEffects()
if(card->view) if(card->view)
card->view->alpha = 255; card->view->alpha = 255;
} }
if (card->target && isInPlay(card->target) && (card->hasSubtype("equipment") || card->hasSubtype("aura"))) if (card->target && isInPlay(card->target) && (card->hasSubtype(Subtypes::TYPE_EQUIPMENT) || card->hasSubtype(Subtypes::TYPE_AURA)))
{ {
card->isPhased = card->target->isPhased; card->isPhased = card->target->isPhased;
card->phasedTurn = card->target->phasedTurn; card->phasedTurn = card->target->phasedTurn;
@@ -681,7 +681,7 @@ void GameObserver::enchantmentStatus()
for (int k = zone->nb_cards - 1; k >= 0; k--) for (int k = zone->nb_cards - 1; k >= 0; k--)
{ {
MTGCardInstance * card = zone->cards[k]; MTGCardInstance * card = zone->cards[k];
if (card && !card->hasType("equipment") && !card->hasSubtype("aura")) if (card && !card->hasType(Subtypes::TYPE_EQUIPMENT) && !card->hasSubtype(Subtypes::TYPE_AURA))
{ {
card->enchanted = false; card->enchanted = false;
card->auras = 0; card->auras = 0;
@@ -690,7 +690,7 @@ void GameObserver::enchantmentStatus()
for (int j = zone->nb_cards - 1; j >= 0; j--) for (int j = zone->nb_cards - 1; j >= 0; j--)
{ {
MTGCardInstance * card = zone->cards[j]; MTGCardInstance * card = zone->cards[j];
if (card->target && isInPlay(card->target) && !card->hasType("equipment") && card->hasSubtype("aura")) if (card->target && isInPlay(card->target) && !card->hasType(Subtypes::TYPE_EQUIPMENT) && card->hasSubtype(Subtypes::TYPE_AURA))
{ {
card->target->enchanted = true; card->target->enchanted = true;
card->target->auras += 1; card->target->auras += 1;
+8 -6
View File
@@ -3,6 +3,7 @@
#include "CardSelectorSingleton.h" #include "CardSelectorSingleton.h"
#include "GameApp.h" #include "GameApp.h"
#include "GuiPlay.h" #include "GuiPlay.h"
#include "Subtypes.h"
#include "Trash.h" #include "Trash.h"
#define CARD_WIDTH (31) #define CARD_WIDTH (31)
@@ -10,6 +11,7 @@
const float GuiPlay::HORZWIDTH = 300.0f; const float GuiPlay::HORZWIDTH = 300.0f;
const float GuiPlay::VERTHEIGHT = 80.0f; const float GuiPlay::VERTHEIGHT = 80.0f;
void GuiPlay::CardStack::reset(unsigned total, float x, float y) void GuiPlay::CardStack::reset(unsigned total, float x, float y)
{ {
this->total = total; this->total = total;
@@ -177,7 +179,7 @@ GuiPlay::~GuiPlay()
bool isSpell(CardView* c) bool isSpell(CardView* c)
{ {
return c->card->isSpell() && !c->card->isCreature() && !c->card->hasType("Planeswalker"); return c->card->isSpell() && !c->card->isCreature() && !c->card->hasType(Subtypes::TYPE_PLANESWALKER);
} }
void GuiPlay::Replace() void GuiPlay::Replace()
{ {
@@ -189,7 +191,7 @@ void GuiPlay::Replace()
for (iterator it = cards.begin(); it != end_spells; ++it) for (iterator it = cards.begin(); it != end_spells; ++it)
if (!(*it)->card->target) if (!(*it)->card->target)
{ {
if(!(*it)->card->hasSubtype("aura") && !(*it)->card->hasType("Planeswalker")) if(!(*it)->card->hasSubtype(Subtypes::TYPE_AURA) && !(*it)->card->hasType(Subtypes::TYPE_PLANESWALKER))
{ {
if (game->players[0] == (*it)->card->controller()) if (game->players[0] == (*it)->card->controller())
++selfSpellsN; ++selfSpellsN;
@@ -210,7 +212,7 @@ void GuiPlay::Replace()
else else
++opponentCreaturesN; ++opponentCreaturesN;
} }
else if ((*it)->card->isLand() || (*it)->card->hasType("Planeswalker")) else if ((*it)->card->isLand() || (*it)->card->hasType(Subtypes::TYPE_PLANESWALKER))
{ {
if (game->players[0] == (*it)->card->controller()) if (game->players[0] == (*it)->card->controller())
++selfLandsN; ++selfLandsN;
@@ -225,7 +227,7 @@ void GuiPlay::Replace()
for (iterator it = cards.begin(); it != end_spells; ++it) for (iterator it = cards.begin(); it != end_spells; ++it)
if (!(*it)->card->target) if (!(*it)->card->target)
{ {
if(!(*it)->card->hasSubtype("aura") && !(*it)->card->hasType("Planeswalker")) if(!(*it)->card->hasSubtype(Subtypes::TYPE_AURA) && !(*it)->card->hasType(Subtypes::TYPE_PLANESWALKER))
{ {
if (game->players[0] == (*it)->card->controller()) if (game->players[0] == (*it)->card->controller())
selfSpells.Enstack(*it); selfSpells.Enstack(*it);
@@ -268,7 +270,7 @@ void GuiPlay::Replace()
//rerun the iter reattaching planes walkers to the back of the lands. //rerun the iter reattaching planes walkers to the back of the lands.
for (iterator it = end_spells; it != cards.end(); ++it) for (iterator it = end_spells; it != cards.end(); ++it)
{ {
if ((*it)->card->hasType("Planeswalker")) if ((*it)->card->hasType(Subtypes::TYPE_PLANESWALKER))
{ {
if (game->players[0] == (*it)->card->controller()) if (game->players[0] == (*it)->card->controller())
selfLands.Enstack(*it); selfLands.Enstack(*it);
@@ -297,7 +299,7 @@ void GuiPlay::Render()
else else
opponentCreatures.Render(*it, cards.begin(), end_spells); opponentCreatures.Render(*it, cards.begin(), end_spells);
} }
else if(!(*it)->card->hasType("Planeswalker")) else if(!(*it)->card->hasType(Subtypes::TYPE_PLANESWALKER))
{ {
if (!(*it)->card->target) if (!(*it)->card->target)
{ {
+12 -12
View File
@@ -1214,7 +1214,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
oneShot = 1; oneShot = 1;
if (activated) if (activated)
oneShot = 1; oneShot = 1;
if (card->hasType("sorcery") || card->hasType("instant")) if (card->hasType(Subtypes::TYPE_SORCERY) || card->hasType(Subtypes::TYPE_INSTANT))
oneShot = 1; oneShot = 1;
if (a->oneShot) if (a->oneShot)
oneShot = 1; oneShot = 1;
@@ -1304,7 +1304,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
oneShot = 1; oneShot = 1;
if (a->oneShot) if (a->oneShot)
oneShot = 1; oneShot = 1;
if (card->hasType("sorcery") || card->hasType("instant")) if (card->hasType(Subtypes::TYPE_SORCERY) || card->hasType(Subtypes::TYPE_INSTANT))
oneShot = 1; oneShot = 1;
found = s.find("while "); found = s.find("while ");
if (found != string::npos) if (found != string::npos)
@@ -1868,7 +1868,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
//hack for http://code.google.com/p/wagic/issues/detail?id=120 //hack for http://code.google.com/p/wagic/issues/detail?id=120
//We assume that auras don't move their own target... //We assume that auras don't move their own target...
if (card->hasType("aura")) if (card->hasType(Subtypes::TYPE_AURA))
target = card; target = card;
MTGAbility * a = NEW AAMover(id, card, target, szone); MTGAbility * a = NEW AAMover(id, card, target, szone);
@@ -2300,7 +2300,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
t = spell->getNextTarget(); t = spell->getNextTarget();
if (!activated) if (!activated)
{ {
if (card->hasType("instant") || card->hasType("sorcery") || forceUEOT) if (card->hasType(Subtypes::TYPE_INSTANT) || card->hasType(Subtypes::TYPE_SORCERY) || forceUEOT)
{ {
return NEW AInstantCastRestrictionUEOT(id, card, t, castTargets, value, modifyExisting, kMaxCastZones[i], who); return NEW AInstantCastRestrictionUEOT(id, card, t, castTargets, value, modifyExisting, kMaxCastZones[i], who);
} }
@@ -2608,7 +2608,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
{ {
if (!activated) if (!activated)
{ {
if (card->hasType("instant") || card->hasType("sorcery") || forceUEOT) if (card->hasType(Subtypes::TYPE_INSTANT) || card->hasType(Subtypes::TYPE_SORCERY) || forceUEOT)
{ {
return NEW AInstantPowerToughnessModifierUntilEOT(id, card, target, wppt); return NEW AInstantPowerToughnessModifierUntilEOT(id, card, target, wppt);
} }
@@ -2647,7 +2647,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
fromTc->setAllZones(); fromTc->setAllZones();
if (!activated) if (!activated)
{ {
if (card->hasType("instant") || card->hasType("sorcery") || forceUEOT) if (card->hasType(Subtypes::TYPE_INSTANT) || card->hasType(Subtypes::TYPE_SORCERY) || forceUEOT)
{ {
return NULL; //TODO return NULL; //TODO
} }
@@ -2668,7 +2668,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
fromTc->setAllZones(); fromTc->setAllZones();
if (!activated) if (!activated)
{ {
if (card->hasType("instant") || card->hasType("sorcery") || forceUEOT) if (card->hasType(Subtypes::TYPE_INSTANT) || card->hasType(Subtypes::TYPE_SORCERY) || forceUEOT)
{ {
return NULL; //TODO return NULL; //TODO
} }
@@ -2690,7 +2690,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
//default target zone to opponentbattlefield here? //default target zone to opponentbattlefield here?
if (!activated) if (!activated)
{ {
if (card->hasType("instant") || card->hasType("sorcery") || forceUEOT) if (card->hasType(Subtypes::TYPE_INSTANT) || card->hasType(Subtypes::TYPE_SORCERY) || forceUEOT)
{ {
return NULL; //TODO return NULL; //TODO
} }
@@ -2797,7 +2797,7 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
} }
if (!activated) if (!activated)
{ {
if (card->hasType("instant") || card->hasType("sorcery") || forceUEOT) if (card->hasType(Subtypes::TYPE_INSTANT) || card->hasType(Subtypes::TYPE_SORCERY) || forceUEOT)
{ {
return NEW AInstantBasicAbilityModifierUntilEOT(id, card, target, j, modifier); return NEW AInstantBasicAbilityModifierUntilEOT(id, card, target, j, modifier);
} }
@@ -3073,7 +3073,7 @@ int AbilityFactory::getAbilities(vector<MTGAbility *> * v, Spell * spell, MTGCar
magicText.append(faceupC); magicText.append(faceupC);
} }
else if(card && card->hasType("equipment") && card->target) else if(card && card->hasType(Subtypes::TYPE_EQUIPMENT) && card->target)
{ {
magicText = card->model->data->magicText; magicText = card->model->data->magicText;
string equipText = card->magicTexts["skill"]; string equipText = card->magicTexts["skill"];
@@ -3451,7 +3451,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell)
for (int j = inplay->nb_cards - 1; j >= 0; j--) for (int j = inplay->nb_cards - 1; j >= 0; j--)
{ {
MTGCardInstance * card = inplay->cards[j]; MTGCardInstance * card = inplay->cards[j];
if (card->owner == player && card->hasType("artifact")) if (card->owner == player && card->hasType(Subtypes::TYPE_ARTIFACT))
{ {
player->game->putInZone(card, inplay, player->game->hand); player->game->putInZone(card, inplay, player->game->hand);
} }
@@ -3780,7 +3780,7 @@ void AbilityFactory::addAbilities(int _id, Spell * spell)
if(card->previous && card->previous->previous && card->previous->previous->suspended) if(card->previous && card->previous->previous && card->previous->previous->suspended)
card->basicAbilities[Constants::HASTE] = 1; card->basicAbilities[Constants::HASTE] = 1;
if (card->hasType("instant") || card->hasType("sorcery")) if (card->hasType(Subtypes::TYPE_INSTANT) || card->hasType(Subtypes::TYPE_SORCERY))
{ {
MTGPlayerCards * zones = card->controller()->game; MTGPlayerCards * zones = card->controller()->game;
if (card->alternateCostPaid[ManaCost::MANA_PAID_WITH_BUYBACK] > 0) if (card->alternateCostPaid[ManaCost::MANA_PAID_WITH_BUYBACK] > 0)
+12 -9
View File
@@ -5,6 +5,7 @@
#include "GameOptions.h" #include "GameOptions.h"
#include "WEvent.h" #include "WEvent.h"
#include "MTGDeck.h" #include "MTGDeck.h"
#include "Subtypes.h"
#if defined (WIN32) || defined (LINUX) #if defined (WIN32) || defined (LINUX)
#include <time.h> #include <time.h>
@@ -133,7 +134,7 @@ void MTGPlayerCards::OptimizedHand(Player * who,int amount, int lands, int creat
{ {
MTGCardInstance * _card = z->cards[j]; MTGCardInstance * _card = z->cards[j];
//------------- //-------------
if (_card->hasType("Land") && optimizedland < lands) if (_card->isLand() && optimizedland < lands)
{ {
card = _card; card = _card;
if (card) if (card)
@@ -143,8 +144,8 @@ void MTGPlayerCards::OptimizedHand(Player * who,int amount, int lands, int creat
} }
} }
//----------------first try to optimize a few cards that cost 2 or less. //----------------first try to optimize a few cards that cost 2 or less.
if (_card->getManaCost()->getConvertedCost() <= 2 && optimizedothercards < othercards && !_card->hasType("Land") if (_card->getManaCost()->getConvertedCost() <= 2 && optimizedothercards < othercards && !_card->isLand()
&& !_card->hasType("Creature")) && !_card->isCreature())
{ {
card = _card; card = _card;
if (card) if (card)
@@ -153,7 +154,7 @@ void MTGPlayerCards::OptimizedHand(Player * who,int amount, int lands, int creat
optimizedothercards += 1; optimizedothercards += 1;
} }
} }
if (_card->getManaCost()->getConvertedCost() <= 2 && optimizedcreatures < creatures && _card->hasType("Creature")) if (_card->getManaCost()->getConvertedCost() <= 2 && optimizedcreatures < creatures && _card->isCreature())
{ {
card = _card; card = _card;
if (card) if (card)
@@ -168,8 +169,8 @@ void MTGPlayerCards::OptimizedHand(Player * who,int amount, int lands, int creat
{ {
MTGCardInstance * _card = z->cards[k]; MTGCardInstance * _card = z->cards[k];
if (_card->getManaCost()->getConvertedCost() <= 3 && optimizedothercards < othercards && (!_card->hasType("Land") if (_card->getManaCost()->getConvertedCost() <= 3 && optimizedothercards < othercards && (!_card->isLand()
|| _card->hasType("Creature"))) || _card->isCreature()))
{ {
card = _card; card = _card;
if (card) if (card)
@@ -178,8 +179,8 @@ void MTGPlayerCards::OptimizedHand(Player * who,int amount, int lands, int creat
optimizedothercards += 1; optimizedothercards += 1;
} }
} }
if (_card->getManaCost()->getConvertedCost() <= 3 && optimizedcreatures < creatures && (_card->hasType("Creature") if (_card->getManaCost()->getConvertedCost() <= 3 && optimizedcreatures < creatures && (_card->isCreature()
|| !_card->hasType("Land"))) || !_card->isLand()))
{ {
card = _card; card = _card;
if (card) if (card)
@@ -478,15 +479,17 @@ MTGCardInstance * MTGGameZone::hasCard(MTGCardInstance * card)
int MTGGameZone::countByType(const char * value) int MTGGameZone::countByType(const char * value)
{ {
int result = 0; int result = 0;
int subTypeId = Subtypes::subtypesList->find(value);
for (int i = 0; i < (nb_cards); i++) for (int i = 0; i < (nb_cards); i++)
{ {
if (cards[i]->hasType(value)) if (cards[i]->hasType(subTypeId))
{ {
result++; result++;
} }
} }
return result; return result;
} }
int MTGGameZone::countByCanTarget(TargetChooser * tc) int MTGGameZone::countByCanTarget(TargetChooser * tc)
{ {
if(!tc) if(!tc)
+8 -8
View File
@@ -38,7 +38,7 @@ int MTGPutInPlayRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
if(!allowedToCast(card,player)) if(!allowedToCast(card,player))
return 0; return 0;
if (card->hasType("land")) if (card->isLand())
{ {
if (currentPlayer->game->playRestrictions->canPutIntoZone(card, currentPlayer->game->inPlay) == PlayRestriction::CANT_PLAY) if (currentPlayer->game->playRestrictions->canPutIntoZone(card, currentPlayer->game->inPlay) == PlayRestriction::CANT_PLAY)
return 0; return 0;
@@ -49,7 +49,7 @@ int MTGPutInPlayRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
return 1; return 1;
} }
} }
else if ((card->hasType("instant")) || card->has(Constants::FLASH) else if ((card->hasType(Subtypes::TYPE_INSTANT)) || card->has(Constants::FLASH)
|| (player == currentPlayer && !game->isInterrupting || (player == currentPlayer && !game->isInterrupting
&& (game->currentGamePhase == Constants::MTG_PHASE_FIRSTMAIN && (game->currentGamePhase == Constants::MTG_PHASE_FIRSTMAIN
|| game->currentGamePhase == Constants::MTG_PHASE_SECONDMAIN)) || game->currentGamePhase == Constants::MTG_PHASE_SECONDMAIN))
@@ -127,7 +127,7 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card)
ManaCost * spellCost = previousManaPool->Diff(player->getManaPool()); ManaCost * spellCost = previousManaPool->Diff(player->getManaPool());
delete previousManaPool; delete previousManaPool;
if (card->hasType("land")) if (card->isLand())
{ {
MTGCardInstance * copy = player->game->putInZone(card, player->game->hand, player->game->temp); MTGCardInstance * copy = player->game->putInZone(card, player->game->hand, player->game->temp);
Spell * spell = NEW Spell(0,copy,NULL,NULL, payResult); Spell * spell = NEW Spell(0,copy,NULL,NULL, payResult);
@@ -224,7 +224,7 @@ int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *
if(!allowedToAltCast(card,player)) if(!allowedToAltCast(card,player))
return 0; return 0;
if (card->hasType("land")) if (card->isLand())
{ {
if (currentPlayer->game->playRestrictions->canPutIntoZone(card, currentPlayer->game->inPlay) == PlayRestriction::CANT_PLAY) if (currentPlayer->game->playRestrictions->canPutIntoZone(card, currentPlayer->game->inPlay) == PlayRestriction::CANT_PLAY)
return 0; return 0;
@@ -234,7 +234,7 @@ int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *
) )
return 1; return 1;
} }
else if ((card->hasType("instant")) || card->has(Constants::FLASH) else if ((card->hasType(Subtypes::TYPE_INSTANT)) || card->has(Constants::FLASH)
|| (player == currentPlayer && !game->isInterrupting || (player == currentPlayer && !game->isInterrupting
&& (game->currentGamePhase == Constants::MTG_PHASE_FIRSTMAIN && (game->currentGamePhase == Constants::MTG_PHASE_FIRSTMAIN
|| game->currentGamePhase == Constants::MTG_PHASE_SECONDMAIN)) || game->currentGamePhase == Constants::MTG_PHASE_SECONDMAIN))
@@ -295,7 +295,7 @@ int MTGAlternativeCostRule::reactToClick(MTGCardInstance * card, ManaCost *alter
card->alternateCostPaid[alternateCostType] = 1; card->alternateCostPaid[alternateCostType] = 1;
if (card->hasType("land")) if (card->isLand())
{ {
MTGCardInstance * copy = player->game->putInZone(card, card->currentZone, player->game->temp); MTGCardInstance * copy = player->game->putInZone(card, card->currentZone, player->game->temp);
Spell * spell = NEW Spell(0,copy,NULL,NULL, alternateCostType); Spell * spell = NEW Spell(0,copy,NULL,NULL, alternateCostType);
@@ -642,7 +642,7 @@ int MTGMorphCostRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
if(!allowedToAltCast(card,player)) if(!allowedToAltCast(card,player))
return 0; return 0;
//note lands can morph too, this is different from other cost types. //note lands can morph too, this is different from other cost types.
if ((card->hasType("instant")) || card->has(Constants::FLASH) || (player == currentPlayer if ((card->hasType(Subtypes::TYPE_INSTANT)) || card->has(Constants::FLASH) || (player == currentPlayer
&& !game->isInterrupting && !game->isInterrupting
&& (game->currentGamePhase == Constants::MTG_PHASE_FIRSTMAIN && (game->currentGamePhase == Constants::MTG_PHASE_FIRSTMAIN
|| game->currentGamePhase == Constants::MTG_PHASE_SECONDMAIN)) || game->currentGamePhase == Constants::MTG_PHASE_SECONDMAIN))
@@ -1571,7 +1571,7 @@ int MTGPlaneWalkerRule::canBeInList(MTGCardInstance * card)
{ {
if(card->isPhased) if(card->isPhased)
return 0; return 0;
if (card->hasType("Planeswalker") && game->isInPlay(card)) if (card->hasType(Subtypes::TYPE_PLANESWALKER) && game->isInPlay(card))
{ {
return 1; return 1;
} }
+3 -6
View File
@@ -15,6 +15,9 @@ Subtypes::Subtypes()
find("Land"); find("Land");
find("Artifact"); find("Artifact");
find("Legendary"); find("Legendary");
find("Equipment");
find("Aura");
find("Planeswalker");
} }
int Subtypes::find(string value, bool forceAdd) int Subtypes::find(string value, bool forceAdd)
@@ -29,12 +32,6 @@ int Subtypes::find(string value, bool forceAdd)
return id; return id;
} }
int Subtypes::find(const char * subtype, bool forceAdd)
{
string value = subtype;
return find(value, forceAdd);
}
string Subtypes::find(unsigned int id) string Subtypes::find(unsigned int id)
{ {
if (valuesById.size() < id || !id) return ""; if (valuesById.size() < id || !id) return "";
+1 -1
View File
@@ -754,7 +754,7 @@ bool TargetChooser::canTarget(Targetable * target,bool withoutProtections)
tempcard = tempcard->previous; tempcard = tempcard->previous;
} }
} }
if(source && ((source->hasSubtype("aura") || source->hasSubtype("equipment")) && source->target && source->target == card && source->target->isPhased && targetter->target == card)) if(source && ((source->hasSubtype(Subtypes::TYPE_AURA) || source->hasSubtype(Subtypes::TYPE_EQUIPMENT)) && source->target && source->target == card && source->target->isPhased && targetter->target == card))
return true; return true;
//this is kinda cheating but by default we let auras and equipments always continue to target a phased creature. //this is kinda cheating but by default we let auras and equipments always continue to target a phased creature.
else if(card->isPhased) else if(card->isPhased)