This commit is contained in:
wagic.the.homebrew
2008-11-02 09:50:16 +00:00
commit d45e3b101b
726 changed files with 179125 additions and 0 deletions
+462
View File
@@ -0,0 +1,462 @@
#include "../include/debug.h"
#include "../include/TargetChooser.h"
#include "../include/MTGGameZones.h"
#include "../include/GameObserver.h"
#include "../include/Subtypes.h"
TargetChooser * TargetChooserFactory::createTargetChooser(string s, MTGCardInstance * card){
GameObserver * game = GameObserver::GetInstance();
MTGGameZone * zones[10];
int nbzones = 0;
int size = s.size();
if (size != 0){
unsigned int found;
found = s.find("player");
if (found != string::npos){
int maxtargets = 1;
unsigned int several = s.find_first_of('s',5);
if (several != string::npos) maxtargets = -1;
found = s.find("creature");
if (found != string::npos){
return NEW DamageableTargetChooser(card,maxtargets); //Any Damageable target (player, creature)
}else{
return NEW PlayerTargetChooser(card,maxtargets); //Any player
}
}else{
string s1;
found = s.find("|");
if (found != string::npos){
string s2;
s1 = s.substr(0,found);
s2 = s.substr(found+1);
while(s2.size()){
found = s2.find(",");
string zoneName;
if (found != string::npos){
zoneName = s2.substr(0,found);
s2 = s2.substr(found+1);
}else{
zoneName = s2;
s2 = "";
}
//Graveyards
if (zoneName.compare("mygraveyard") == 0){
zones[nbzones] = game->currentlyActing()->game->graveyard;
}else if(zoneName.compare("opponentgraveyard") == 0){
zones[nbzones] = game->currentlyActing()->opponent()->game->graveyard;
}else if(zoneName.compare("graveyard") == 0){
zones[nbzones] = game->players[0]->game->graveyard;
nbzones++;
zones[nbzones] = game->players[1]->game->graveyard;
}else{
//inPlay
if (zoneName.compare("myinplay") == 0){
zones[nbzones] = game->currentlyActing()->game->inPlay;
}else if(zoneName.compare("opponentinplay") == 0){
zones[nbzones] = game->currentlyActing()->opponent()->game->inPlay;
}else if(zoneName.compare("inplay") == 0){
zones[nbzones] = game->players[0]->game->inPlay;
nbzones++;
zones[nbzones] = game->players[1]->game->inPlay;
}else{
zones[nbzones] = game->currentlyActing()->game->inPlay;
}
}
nbzones++;
}
}else{
s1 = s;
nbzones = 2;
zones[0]= game->players[0]->game->inPlay;
zones[1]= game->players[1]->game->inPlay;
}
TypeTargetChooser * tc = NULL;
int maxtargets = 1;
while(s1.size()){
found = s1.find(",");
string typeName;
if (found != string::npos){
typeName = s1.substr(0,found);
s1 = s1.substr(found+1);
}else{
typeName = s1;
s1 = "";
}
//X targets allowed ?
if (typeName.at(typeName.length()-1) == 's'){
typeName = typeName.substr(0,typeName.length()-1);
maxtargets = -1;
}
if (!tc){
if (typeName.compare("*")==0){
return NEW TargetZoneChooser(zones, nbzones,card, maxtargets);
}else{
tc = NEW TypeTargetChooser(typeName.c_str(), zones, nbzones, card,maxtargets);
}
}else{
tc->addType(typeName.c_str());
tc->maxtargets = maxtargets;
}
}
return tc;
}
}
return NULL;
}
TargetChooser * TargetChooserFactory::createTargetChooser(MTGCardInstance * card){
int id = card->model->getId();
string s = card->spellTargetType;
if (card->alias){
id = card->alias;
//TODO load target as well... ?
}
TargetChooser * tc = createTargetChooser(s, card);
if (tc) return tc;
//Any target than cannot be defined automatically is determined by its id
switch (id){
//Spell
case 1196: //CounterSpell
case 1224: //Spell blast
{
#if defined (WIN32) || defined (LINUX)
OutputDebugString ("Counter Spell !\n");
#endif
return NEW SpellTargetChooser(card);
}
//Spell Or Permanent
case 1282: //ChaosLace
case 1152: //DeathLace
case 1358: //PureLace
case 1227: //ThoughLace
case 1257: //Lifelace
{
return NEW SpellOrPermanentTargetChooser(card);
}
//Red Spell or Permanent
case 1191: //Blue Elemental Blast
{
return NEW SpellOrPermanentTargetChooser(card,MTG_COLOR_RED);
}
//Blue Spell or Permanent
case 1312: //Red Elemental Blast
{
return NEW SpellOrPermanentTargetChooser(card,MTG_COLOR_BLUE);
}
//Damage History
case 1344: //Eye for an Eye
{
return NEW DamageTargetChooser(card,-1,1,RESOLVED_OK);
}
default:
{
return NULL;
}
}
}
TargetChooser::TargetChooser(MTGCardInstance * card, int _maxtargets): TargetsList(){
forceTargetListReady = 0;
source = card;
maxtargets = _maxtargets;
}
//Default targetter : every card can be targetted, unless it is protected from the source card
int TargetChooser::canTarget(Targetable * target){
if (target->typeAsTarget() == TARGET_CARD){
MTGCardInstance * card = (MTGCardInstance *) target;
if (source && card->protectedAgainst(source)) return 0;
return 1;
}
return 0;
}
int TargetChooser::addTarget(Targetable * target){
if (canTarget(target) && TargetsList::addTarget(target)){
}
#if defined (WIN32) || defined (LINUX)
char buf[4096];
sprintf(buf, "Nb targets : %i\n", cursor);
OutputDebugString(buf);
#endif
return targetsReadyCheck();
}
int TargetChooser::ForceTargetListReady(){
int state = targetsReadyCheck() ;
if (state == TARGET_OK){
forceTargetListReady = 1;
}
return forceTargetListReady;
}
int TargetChooser::targetsReadyCheck(){
if (cursor == 0){
return TARGET_NOK;
}
if (full()){
return TARGET_OK_FULL;
}
if (!ready()){
return TARGET_OK_NOT_READY;
}
return TARGET_OK;
}
int TargetChooser::targetListSet(){
int state = targetsReadyCheck();
if (state == TARGET_OK_FULL || forceTargetListReady){
return 1;
}
return 0;
}
/**
Choose anything that has a given list of types
**/
TypeTargetChooser::TypeTargetChooser(const char * _type, MTGCardInstance * card, int _maxtargets):TargetZoneChooser(card, _maxtargets){
int id = Subtypes::subtypesList->Add(_type);
nbtypes = 0;
addType(id);
GameObserver * game = GameObserver::GetInstance();
MTGGameZone * default_zones[] = {game->players[0]->game->inPlay, game->players[1]->game->inPlay};
init(default_zones,2);
}
TypeTargetChooser::TypeTargetChooser(const char * _type, MTGGameZone ** _zones, int nbzones, MTGCardInstance * card, int _maxtargets):TargetZoneChooser(card, _maxtargets){
int id = Subtypes::subtypesList->Add(_type);
nbtypes = 0;
addType(id);
GameObserver * game = GameObserver::GetInstance();
if (nbzones == 0){
MTGGameZone * default_zones[] = {game->players[0]->game->inPlay, game->players[1]->game->inPlay};
init(default_zones,2);
}else{
init(_zones, nbzones);
}
}
void TypeTargetChooser::addType(const char * _type){
int id = Subtypes::subtypesList->Add(_type);
addType(id);
}
void TypeTargetChooser::addType(int type){
types[nbtypes] = type;
nbtypes++;
}
int TypeTargetChooser::canTarget(Targetable * target ){
if (target->typeAsTarget() == TARGET_CARD){
MTGCardInstance * card = (MTGCardInstance *) target;
if (!TargetZoneChooser::canTarget(card)) return 0;
int result = 0;
for (int i= 0; i < nbtypes; i++){
result += card->hasSubtype(types[i]);
}
return result;
}
return 0;
}
/**
Choose a creature anywhere. This is actually not enough as a zone should be selected
**/
CreatureTargetChooser::CreatureTargetChooser( MTGCardInstance * card, int _maxtargets):TargetZoneChooser(card, _maxtargets){
GameObserver * game = GameObserver::GetInstance();
MTGGameZone * default_zones[] = {game->players[0]->game->inPlay, game->players[1]->game->inPlay};
init(default_zones,2);
maxpower= -1;
}
CreatureTargetChooser::CreatureTargetChooser(MTGGameZone ** _zones, int nbzones, MTGCardInstance * card, int _maxtargets):TargetZoneChooser(card, _maxtargets){
GameObserver * game = GameObserver::GetInstance();
if (nbzones == 0){
MTGGameZone * default_zones[] = {game->players[0]->game->inPlay, game->players[1]->game->inPlay};
init(default_zones,2);
}else{
init(_zones, nbzones);
}
maxpower = -1;
}
int CreatureTargetChooser::canTarget(Targetable * target){
if (!TargetZoneChooser::canTarget(target)) return 0;
if (target->typeAsTarget() == TARGET_CARD){
MTGCardInstance * card = (MTGCardInstance *) target;
if (maxpower != -1 && card->power > maxpower) return 0;
return card->isACreature();
}
return 0;
}
TargetZoneChooser::TargetZoneChooser(MTGCardInstance * card, int _maxtargets){
init(NULL,0);
source = card;
maxtargets = _maxtargets;
}
TargetZoneChooser::TargetZoneChooser(MTGGameZone ** _zones, int _nbzones,MTGCardInstance * card, int _maxtargets){
init(_zones, _nbzones);
source = card;
maxtargets = _maxtargets;
}
int TargetZoneChooser::init(MTGGameZone ** _zones, int _nbzones){
for (int i = 0; i < _nbzones; i++){
zones[i] = _zones[i];
}
nbzones = _nbzones;
return nbzones;
}
int TargetZoneChooser::canTarget(Targetable * target){
if (!TargetChooser::canTarget(target)) return 0;
if (target->typeAsTarget() == TARGET_CARD){
MTGCardInstance * card = (MTGCardInstance *) target;
for (int i = 0; i<nbzones; i++){
if (zones[i]->hasCard(card)) return 1;
}
}
return 0;
}
/* Player Target */
int PlayerTargetChooser::canTarget(Targetable * target){
if (target->typeAsTarget() == TARGET_PLAYER){
return 1;
}
return 0;
}
/*Damageable Target */
int DamageableTargetChooser::canTarget(Targetable * target){
if (target->typeAsTarget() == TARGET_PLAYER){
#if defined (WIN32) || defined (LINUX)
OutputDebugString("Targetting Player !!!\n");
#endif
return 1;
}
return CreatureTargetChooser::canTarget(target);
}
/*Spell */
SpellTargetChooser::SpellTargetChooser(MTGCardInstance * card,int _color, int _maxtargets ):TargetChooser(card, _maxtargets){
color = _color;
}
int SpellTargetChooser::canTarget(Targetable * target){
MTGCardInstance * card = NULL;
if (target->typeAsTarget() == TARGET_STACKACTION){
Interruptible * action = (Interruptible *) target;
if (action->type == ACTION_SPELL && action->state==NOT_RESOLVED){
Spell * spell = (Spell *) action;
card = spell->source;
if (card && (color == -1 || card->hasColor(color))) return 1;
}
}
return 0;
}
/*Spell or Permanent */
SpellOrPermanentTargetChooser::SpellOrPermanentTargetChooser(MTGCardInstance * card,int _color, int _maxtargets):TargetZoneChooser(card, _maxtargets){
GameObserver * game = GameObserver::GetInstance();
MTGGameZone * default_zones[] = {game->players[0]->game->inPlay, game->players[1]->game->inPlay};
init(default_zones,2);
color = _color;
}
int SpellOrPermanentTargetChooser::canTarget(Targetable * target){
MTGCardInstance * card = NULL;
if (target->typeAsTarget() == TARGET_CARD){
card = (MTGCardInstance *) target;
if (color == -1 || card->hasColor(color)) return TargetZoneChooser::canTarget(target);
}else if (target->typeAsTarget() == TARGET_STACKACTION){
Interruptible * action = (Interruptible *) target;
if (action->type == ACTION_SPELL && action->state==NOT_RESOLVED){
Spell * spell = (Spell *) action;
card = spell->source;
if (card && (color == -1 || card->hasColor(color))) return 1;
}
}
return 0;
}
/*Damage */
DamageTargetChooser::DamageTargetChooser(MTGCardInstance * card,int _color, int _maxtargets, int _state):TargetChooser(card, _maxtargets){
color = _color;
state = _state;
}
int DamageTargetChooser::canTarget(Targetable * target){
MTGCardInstance * card = NULL;
if (target->typeAsTarget() == TARGET_STACKACTION){
Interruptible * action = (Interruptible *) target;
if (action->type == ACTION_DAMAGE && (action->state == state || state == -1)){
Damage * damage = (Damage *) action;
card = damage->source;
if (card && (color == -1 || card->hasColor(color))) return 1;
}
}
return 0;
}
/*Damage or Permanent */
DamageOrPermanentTargetChooser::DamageOrPermanentTargetChooser(MTGCardInstance * card,int _color, int _maxtargets):TargetZoneChooser(card, _maxtargets){
GameObserver * game = GameObserver::GetInstance();
MTGGameZone * default_zones[] = {game->players[0]->game->inPlay, game->players[1]->game->inPlay};
init(default_zones,2);
color = _color;
}
int DamageOrPermanentTargetChooser::canTarget(Targetable * target){
MTGCardInstance * card = NULL;
if (target->typeAsTarget() == TARGET_CARD){
card = (MTGCardInstance *) target;
if (color == -1 || card->hasColor(color)) return TargetZoneChooser::canTarget(target);
}else if (target->typeAsTarget() == TARGET_STACKACTION){
Interruptible * action = (Interruptible *) target;
if (action->type == ACTION_DAMAGE){
Damage * damage = (Damage *) action;
card = damage->source;
if (card && (color == -1 || card->hasColor(color))) return 1;
}
}
return 0;
}