diff --git a/projects/mtg/bin/Res/sets/SHM/_cards.dat b/projects/mtg/bin/Res/sets/SHM/_cards.dat index 810a74486..9eb359356 100644 --- a/projects/mtg/bin/Res/sets/SHM/_cards.dat +++ b/projects/mtg/bin/Res/sets/SHM/_cards.dat @@ -40,6 +40,7 @@ toughness=4 [card] text=Plainswalk {2}{R}, Sacrifice Boggart Arsonists: Destroy target Scarecrow or Plains. auto={2}{R}{S}:destroy target(scarecrow,plains) +abilities=plainswalk id=158684 name=Boggart Arsonists rarity=C diff --git a/projects/mtg/bin/Res/sets/TMP/_cards.dat b/projects/mtg/bin/Res/sets/TMP/_cards.dat index a9653e1a7..e15138a0d 100644 --- a/projects/mtg/bin/Res/sets/TMP/_cards.dat +++ b/projects/mtg/bin/Res/sets/TMP/_cards.dat @@ -27,6 +27,14 @@ mana={2}{R}{R} type=Sorcery [/card] [card] +text={T}: Add {2} to your mana pool. Ancient Tomb deals 2 damage to you. +auto={T}: Add {2} && Damage 1 controller +id=4636 +name=Ancient Tomb +rarity=U +type=Land +[/card] +[card] text=Flying id=4861 name=Armored Pegasus @@ -283,6 +291,15 @@ mana={2}{U}{U} type=Instant [/card] [card] +text=White creatures get -1/-1. +auto=lord(creature[white]) -1/-1 +id=4658 +name=Dread of Night +rarity=U +type=Enchantment +mana={B} +[/card] +[card] text=Legendary Other Elf creatures have forestwalk. Other Elves have shroud. (They can't be the targets of spells or abilities.) id=4757 name=Eladamri, Lord of Leaves @@ -619,6 +636,19 @@ toughness=1 abilities=Haste [/card] [card] +text={T}, Sacrifice Lotus Petal: Add one mana of any color to your mana pool. +auto={T},{S}:Add{G} +auto={T},{S}:Add{R} +auto={T},{S}:Add{U} +auto={T},{S}:Add{B} +auto={T},{S}:Add{W} +id=4614 +name=Lotus Petal +rarity=C +type=Artifact +mana={0} +[/card] +[card] id=4829 name=Lowland Giant colour=Red diff --git a/projects/mtg/bin/Res/sets/TMP/todo.dat b/projects/mtg/bin/Res/sets/TMP/todo.dat index f77651658..48c655769 100644 --- a/projects/mtg/bin/Res/sets/TMP/todo.dat +++ b/projects/mtg/bin/Res/sets/TMP/todo.dat @@ -49,13 +49,7 @@ rarity=U type=Enchantment mana={2}{R} [/card] -[card] -text={T}: Add {2} to your mana pool. Ancient Tomb deals 2 damage to you. -id=4636 -name=Ancient Tomb -rarity=U -type=Land -[/card] + [card] text=Flying Whenever Angelic Protector becomes the target of a spell or ability, Angelic Protector gets +0/+3 until end of turn. id=4858 @@ -696,14 +690,7 @@ power=0 subtype=Shapeshifter toughness=0 [/card] -[card] -text=White creatures get -1/-1. -id=4658 -name=Dread of Night -rarity=U -type=Enchantment -mana={B} -[/card] + [card] text=Draw three cards, then put two cards from your hand both on top of your library or both on the bottom of your library. id=4696 @@ -1515,14 +1502,7 @@ rarity=U type=Sorcery mana={2}{U}{B} [/card] -[card] -text={T}, Sacrifice Lotus Petal: Add one mana of any color to your mana pool. -id=4614 -name=Lotus Petal -rarity=C -type=Artifact -mana={0} -[/card] + [card] text= id=4829 diff --git a/projects/mtg/bin/Res/test/_tests.txt b/projects/mtg/bin/Res/test/_tests.txt index c76a1c0c5..1c915dab0 100644 --- a/projects/mtg/bin/Res/test/_tests.txt +++ b/projects/mtg/bin/Res/test/_tests.txt @@ -5,6 +5,7 @@ generic/first_strike.txt generic/first_strike2.txt generic/first_strike3.txt generic/hybrid_mana.txt +generic/hybrid_mana_2.txt generic/legendary.txt generic/persist.txt generic/wither.txt @@ -18,6 +19,8 @@ animate_dead2.txt ardakar_wastes.txt ascendant_evincar.txt ascendant_evincar2.txt +bottle_gnomes.txt +boggart_arsonists.txt brass_man.txt castle.txt celestial_purge.txt @@ -52,9 +55,11 @@ nantuko_husk.txt orcish_lumberjack.txt paralysis.txt paralysis2.txt +protomatter_powder.txt resurrection.txt rootwalla.txt royal_assassin.txt +siege_gang_commander.txt shivan_hellkite.txt shock.txt spark_elemental.txt diff --git a/projects/mtg/bin/Res/test/boggart_arsonists.txt b/projects/mtg/bin/Res/test/boggart_arsonists.txt new file mode 100644 index 000000000..928a884bd --- /dev/null +++ b/projects/mtg/bin/Res/test/boggart_arsonists.txt @@ -0,0 +1,19 @@ +# {2}{R}, Sacrifice Boggart Arsonists: Destroy target Scarecrow or Plains. +[INIT] +FIRSTMAIN +[PLAYER1] +inplay:158684 +manapool:{2}{R} +[PLAYER2] +inplay:154395 +[DO] +158684 +154395 +[ASSERT] +FIRSTMAIN +[PLAYER1] +graveyard:158684 +manapool:{0} +[PLAYER2] +graveyard:154395 +[END] \ No newline at end of file diff --git a/projects/mtg/bin/Res/test/bottle_gnomes.txt b/projects/mtg/bin/Res/test/bottle_gnomes.txt new file mode 100644 index 000000000..f9b4f1b6f --- /dev/null +++ b/projects/mtg/bin/Res/test/bottle_gnomes.txt @@ -0,0 +1,15 @@ +#Do we get 3 life when sacrificing bottle gnomes ? +[INIT] +FIRSTMAIN +[PLAYER1] +inplay:129495 +[PLAYER2] +[DO] +129495 +[ASSERT] +FIRSTMAIN +[PLAYER1] +life:23 +graveyard:129495 +[PLAYER2] +[END] \ No newline at end of file diff --git a/projects/mtg/bin/Res/test/composite_golem.txt b/projects/mtg/bin/Res/test/composite_golem.txt index a3c897a72..122a0adc9 100644 --- a/projects/mtg/bin/Res/test/composite_golem.txt +++ b/projects/mtg/bin/Res/test/composite_golem.txt @@ -1,4 +1,5 @@ #Composite golem sacrifice ability subject to summoning Sickness ? +# Sacrifice composite Golem : Add {W}{U}{B}{R}{G} SummoningSickness [INIT] FIRSTMAIN diff --git a/projects/mtg/bin/Res/test/generic/hybrid_mana_2.txt b/projects/mtg/bin/Res/test/generic/hybrid_mana_2.txt new file mode 100644 index 000000000..1c2903b63 --- /dev/null +++ b/projects/mtg/bin/Res/test/generic/hybrid_mana_2.txt @@ -0,0 +1,18 @@ +#Testing Hybrid Mana +# Spectral possession: text=({2W} can be paid with any two mana or with {W}. This card's converted mana cost is 6.) Put three 1/1 white Spirit creature tokens with flying into play. +[INIT] +FIRSTMAIN +[PLAYER1] +hand:152070 +manapool:{W}{W}{W} +[PLAYER2] +[DO] +152070 +[ASSERT] +FIRSTMAIN +[PLAYER1] +graveyard:152070 +inplay:-152070,-152070,-152070 +manapool:{0} +[PLAYER2] +[END] \ No newline at end of file diff --git a/projects/mtg/bin/Res/test/protomatter_powder.txt b/projects/mtg/bin/Res/test/protomatter_powder.txt new file mode 100644 index 000000000..6bb5ee1ab --- /dev/null +++ b/projects/mtg/bin/Res/test/protomatter_powder.txt @@ -0,0 +1,19 @@ +#text={4}{W}, {T}, Sacrifice Protomatter Powder: Return target artifact card from your graveyard to play. +[INIT] +FIRSTMAIN +[PLAYER1] +inplay:174833 +graveyard:1099 +manapool:{4}{W} +[PLAYER2] +[DO] +174833 +1099 +[ASSERT] +FIRSTMAIN +[PLAYER1] +graveyard:174833 +manapool:{0} +inplay:1099 +[PLAYER2] +[END] \ No newline at end of file diff --git a/projects/mtg/bin/Res/test/siege_gang_commander.txt b/projects/mtg/bin/Res/test/siege_gang_commander.txt new file mode 100644 index 000000000..a22ddb6f0 --- /dev/null +++ b/projects/mtg/bin/Res/test/siege_gang_commander.txt @@ -0,0 +1,25 @@ +#TestingSiege-Gang Commander Sacrifice goblin ability +#text=When Siege-Gang Commander comes into play, put three 1/1 red Goblin creature tokens into play. {1}{R}, Sacrifice a Goblin: Siege-Gang Commander deals 2 damage to target creature or player. +[INIT] +FIRSTMAIN +[PLAYER1] +inplay:130539,130378,129578 +manapool:{2}{R}{R} +[PLAYER2] +inplay:129586,129600 +[DO] +130539 +129586 +129578 +130539 +129600 +130378 +[ASSERT] +FIRSTMAIN +[PLAYER1] +graveyard:130378,129578 +inplay:130539,-130539,-130539,-130539 +manapool:{0} +[PLAYER2] +graveyard:129586,129600 +[END] \ No newline at end of file diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index e7b6bd289..d8f72e40d 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -93,6 +93,28 @@ class ADrawer:public ActivatedAbility{ }; +// Gives/Takes Life to controller of source +class ALifeGiver:public ActivatedAbility{ + public: + int life; + ALifeGiver(int _id, MTGCardInstance * card,ManaCost * _cost, int _life, int _tap = 1):ActivatedAbility(_id, card,_cost,0,_tap),life(_life){ + } + + int resolve(){ + source->controller()->life+=life; + return 1; + } + + + + const char * getMenuText(){ + if (life < 0) return "Lose life"; + return "Gain life"; + } + + +}; + class ATokenCreator:public ActivatedAbility{ public: listabilities; diff --git a/projects/mtg/include/GameStateDeckViewer.h b/projects/mtg/include/GameStateDeckViewer.h index 4ebb2cd31..28b8cf2db 100644 --- a/projects/mtg/include/GameStateDeckViewer.h +++ b/projects/mtg/include/GameStateDeckViewer.h @@ -437,7 +437,7 @@ class GameStateDeckViewer: public GameState, public JGuiListener mFont->DrawString(buffer, SCREEN_WIDTH-120 , y); if (colorFilter != ALL_COLORS){ - sprintf(buffer2, "( %i)", myDeck->getCount(colorFilter)); + sprintf(buffer2, "( %i)", myDeck->getCount(colorFilter)); mFont->DrawString(buffer2, SCREEN_WIDTH-55 , y); JRenderer::GetInstance()->RenderQuad(mIcons[colorFilter], SCREEN_WIDTH-42 , y + 6 , 0.0f,0.5,0.5); } diff --git a/projects/mtg/include/ManaCost.h b/projects/mtg/include/ManaCost.h index f98bcaf82..ac3d6759f 100644 --- a/projects/mtg/include/ManaCost.h +++ b/projects/mtg/include/ManaCost.h @@ -58,6 +58,9 @@ class ManaCost{ int isPositive(); ManaCost * Diff(ManaCost * _cost); +#ifdef WIN32 + void Dump(); +#endif }; #endif diff --git a/projects/mtg/src/ActionLayer.cpp b/projects/mtg/src/ActionLayer.cpp index ff16aaf6a..6e283ff04 100644 --- a/projects/mtg/src/ActionLayer.cpp +++ b/projects/mtg/src/ActionLayer.cpp @@ -126,10 +126,7 @@ int ActionLayer::reactToTargetClick(Targetable * card){ int ActionLayer::isReactingToClick(MTGCardInstance * card){ int result = 0; - for (int i=0;iwaitingForAnswer) return -1; - } + if (isWaitingForAnswer()) return -1; for (int i=0;icontroller()->game->putInGraveyard(target); + target = NULL; + if (tc) tc->initTargets(); return 1; } return 0; diff --git a/projects/mtg/src/GameObserver.cpp b/projects/mtg/src/GameObserver.cpp index 74e493834..20c031faf 100644 --- a/projects/mtg/src/GameObserver.cpp +++ b/projects/mtg/src/GameObserver.cpp @@ -272,11 +272,9 @@ void GameObserver::stackObjectClicked(Interruptible * action){ } void GameObserver::cardClick (MTGCardInstance * card, Targetable * object){ - LOG("==GameObserver::cardClick"); - if (card) {LOG(card->getName())}; Player * clickedPlayer = NULL; if (!card) clickedPlayer = ((Player *)object); - if (targetChooser != NULL){ + if (targetChooser){ int result; if (card) { if (card == cardWaitingForTargets){ diff --git a/projects/mtg/src/GameStateMenu.cpp b/projects/mtg/src/GameStateMenu.cpp index 8154cbe90..903e83e64 100644 --- a/projects/mtg/src/GameStateMenu.cpp +++ b/projects/mtg/src/GameStateMenu.cpp @@ -5,7 +5,7 @@ #include "../include/GameOptions.h" #include "../include/GameApp.h" -static const char* GAME_VERSION = "WTH?! 0.4.0 - by WilLoW"; +static const char* GAME_VERSION = "WTH?! 0.4.1 - by WilLoW"; #define ALPHA_WARNING 0 #define DEFAULT_ANGLE_MULTIPLIER 0.4 diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index f09b569cf..8bc102140 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -373,7 +373,7 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){ }else{ if (dryMode) return BAKA_EFFECT_BAD; if (tc){ - game->addObserver(NEW ADestroyer(id, card,tc)); + game->addObserver(NEW ADestroyer(id, card,tc,0,cost)); }else{ game->mLayers->stackLayer()->addPutInGraveyard(target); } @@ -434,7 +434,7 @@ int AbilityFactory::magicText(int id, Spell * spell, MTGCardInstance * card){ if (!cost && !doTap){ card->controller()->life+=life; }else{ - //TODO; + game->addObserver(NEW ALifeGiver(id, card,cost, life, doTap)); } } result++; @@ -1699,7 +1699,10 @@ ActivatedAbility::~ActivatedAbility(){ if (cost) delete cost; } -// +//The whole targetAbility mechanism is messed up, mainly because of its interactions with +// the ActionLayer, GameObserver, and parent class ActivatedAbility. +// Currently choosing a target is a complete different mechanism for put into play and for other abilities. +// It probably shouldn't be the case. TargetAbility::TargetAbility(int id, MTGCardInstance * card, TargetChooser * _tc,ManaCost * _cost, int _playerturnonly,int tap):ActivatedAbility(id, card,_cost,_playerturnonly, tap){ tc = _tc; @@ -1715,8 +1718,8 @@ void TargetAbility::Update(float dt){ if(mEngine->GetButtonClick(PSP_CTRL_CROSS)){ waitingForAnswer = 0; }else if(tc->targetsReadyCheck() == TARGET_OK_FULL){ - waitingForAnswer = 0; - ActivatedAbility::reactToClick(source); + //waitingForAnswer = 0; + //ActivatedAbility::reactToClick(source); } } } @@ -1724,8 +1727,11 @@ void TargetAbility::Update(float dt){ int TargetAbility::reactToTargetClick(Targetable * object){ if (object->typeAsTarget() == TARGET_CARD) return reactToClick((MTGCardInstance *)object); if (waitingForAnswer){ - tc->toggleTarget(object); - return 1; + if (tc->toggleTarget(object) == TARGET_OK_FULL){ + waitingForAnswer = 0; + return ActivatedAbility::reactToClick(source); + } + return 1; } return 0; } @@ -1740,12 +1746,17 @@ int TargetAbility::reactToClick(MTGCardInstance * card){ } }else{ if (card == source){ - if (tc->targetsReadyCheck() == TARGET_OK){ + if (tc->targetsReadyCheck() == TARGET_OK || tc->targetsReadyCheck() == TARGET_OK_FULL){ waitingForAnswer = 0; return ActivatedAbility::reactToClick(source); } }else{ - tc->toggleTarget(card); + if (tc->toggleTarget(card) == TARGET_OK_FULL){ + + int result = ActivatedAbility::reactToClick(source); + if (result) waitingForAnswer = 0; + return result; + } return 1; } } @@ -1753,7 +1764,7 @@ int TargetAbility::reactToClick(MTGCardInstance * card){ } void TargetAbility::Render(){ - //TODO + //TODO ? } diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index d5ddb06fd..f8a7c2553 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -21,6 +21,9 @@ int MTGPutInPlayRule::isReactingToClick(MTGCardInstance * card){ LOG("CANPUTINPLAY- correct time to play\n"); ManaCost * playerMana = player->getManaPool(); ManaCost * cost = card->getManaCost(); +#ifdef WIN32 + cost->Dump(); +#endif if (playerMana->canAfford(cost)){ LOG("CANPUTINPLAY- ManaCost ok\n"); return 1; diff --git a/projects/mtg/src/ManaCost.cpp b/projects/mtg/src/ManaCost.cpp index 0ac585d8e..83cf53c2c 100644 --- a/projects/mtg/src/ManaCost.cpp +++ b/projects/mtg/src/ManaCost.cpp @@ -70,19 +70,19 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost){ int intvalue = atoi(value.c_str()); int colors[2]; int values[2]; - if (!intvalue && value.size() > 1){ + if (intvalue < 10 && value.size() > 1){ for (int i = 0; i < 2; i++){ char c = value[i]; if (c >='0' && c <='9'){ - colors[i] = Constants::MTG_COLOR_ARTIFACT; - values[i] = c - '0'; + colors[i] = Constants::MTG_COLOR_ARTIFACT; + values[i] = c - '0'; }else{ - for (int j = 0; j < Constants::MTG_NB_COLORS; j++){ - if (c == Constants::MTGColorChars[j]){ - colors[i] = j; - values[i] = 1; - } - } + for (int j = 0; j < Constants::MTG_NB_COLORS; j++){ + if (c == Constants::MTGColorChars[j]){ + colors[i] = j; + values[i] = 1; + } + } } } manaCost->addHybrid(colors[0], values[0], colors[1], values[1]); @@ -98,6 +98,7 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost){ break; } } + return manaCost; } @@ -378,3 +379,25 @@ ManaCost * ManaCost::Diff(ManaCost * _cost){ return result; } + +#ifdef WIN32 +void ManaCost::Dump(){ + char buf[4096]; + OutputDebugString("\n===ManaCost===\n"); + for (int i=0; i<= Constants::MTG_NB_COLORS; i++){ + if (cost[i]) { + sprintf(buf, "%c:%i - ", Constants::MTGColorChars[i],cost[i]); + OutputDebugString(buf); + } + } + + for (int i=0; i< nbhybrids; i++){ + ManaCostHybrid * h = hybrids[i]; + + sprintf(buf, "H:{%c:%i}/{%c:%i}", Constants::MTGColorChars[h->color1], h->value1, Constants::MTGColorChars[h->color2], h->value2); + OutputDebugString(buf); + } + OutputDebugString("\n=============\n"); +} + +#endif \ No newline at end of file diff --git a/projects/mtg/src/TargetChooser.cpp b/projects/mtg/src/TargetChooser.cpp index 550854396..4b1ef024f 100644 --- a/projects/mtg/src/TargetChooser.cpp +++ b/projects/mtg/src/TargetChooser.cpp @@ -189,7 +189,7 @@ OutputDebugString("COLOR FOUND !!!"); typeName = typeName.substr(0,found); } //X targets allowed ? - if (typeName.at(typeName.length()-1) == 's'){ + if (typeName.at(typeName.length()-1) == 's' && !Subtypes::subtypesList->find(typeName)){ typeName = typeName.substr(0,typeName.length()-1); maxtargets = -1; } diff --git a/projects/mtg/src/TestSuiteAI.cpp b/projects/mtg/src/TestSuiteAI.cpp index 94100de5d..b08273ac2 100644 --- a/projects/mtg/src/TestSuiteAI.cpp +++ b/projects/mtg/src/TestSuiteAI.cpp @@ -42,6 +42,7 @@ Interruptible * TestSuite::getActionByMTGId(int mtgid){ return NULL; } + int TestSuiteAI::Act(float dt){ GameObserver * g = GameObserver::GetInstance(); g->gameOver = NULL; // Prevent draw rule from losing the game @@ -211,7 +212,7 @@ void TestSuite::initGame(){ // or go faster when it comes to the whole test suite. //Warning, putting this value too low (< 0.25) will give unexpected results if (!timerLimit){ - timerLimit = 0.3; + timerLimit = 0.5; }else{ timerLimit = 0.1; }