diff --git a/projects/mtg/include/GameOptions.h b/projects/mtg/include/GameOptions.h index 9f8f157ab..8265052ff 100644 --- a/projects/mtg/include/GameOptions.h +++ b/projects/mtg/include/GameOptions.h @@ -53,6 +53,7 @@ public: MAX_GRADE, ASPHASES, FIRSTPLAYER, + KICKERPAYMENT, ECON_DIFFICULTY, TRANSITIONS, GUI_STYLE, @@ -288,6 +289,25 @@ private: static OptionWhosFirst mDef; }; +class OptionKicker : public EnumDefinition +{ +public: + enum + { + KICKER_ALWAYS = 0, + KICKER_CHOICE = 1, + }; + + static EnumDefinition * getInstance() + { + return &mDef; + } + +private: + OptionKicker(); + static OptionKicker mDef; +}; + class OptionEconDifficulty : public EnumDefinition { public: diff --git a/projects/mtg/include/MTGAbility.h b/projects/mtg/include/MTGAbility.h index a75f43489..e17194cbd 100644 --- a/projects/mtg/include/MTGAbility.h +++ b/projects/mtg/include/MTGAbility.h @@ -198,6 +198,7 @@ public: MORPH_COST = 28, SUSPEND_COST = 29, COUNTERS = 30, + PUT_INTO_PLAY_WITH_KICKER = 31, }; diff --git a/projects/mtg/include/MTGDefinitions.h b/projects/mtg/include/MTGDefinitions.h index 31b280e9a..3c5d914fc 100644 --- a/projects/mtg/include/MTGDefinitions.h +++ b/projects/mtg/include/MTGDefinitions.h @@ -227,6 +227,9 @@ CANATTACK = 91, WHO_O=1, WHO_R=2, + KICKER_ALWAYS=0, + KICKER_CHOICE=1, + }; enum{ diff --git a/projects/mtg/include/MTGRules.h b/projects/mtg/include/MTGRules.h index 6dfe56946..7447a7a70 100644 --- a/projects/mtg/include/MTGRules.h +++ b/projects/mtg/include/MTGRules.h @@ -72,11 +72,26 @@ public: MTGPutInPlayRule(int _id); const char * getMenuText() { - return "Play Card Normally"; + return "cast card normally"; } virtual MTGPutInPlayRule * clone() const; }; +class MTGKickerRule: public MTGPutInPlayRule +{ +public: + int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL); + int reactToClick(MTGCardInstance * card); + int testDestroy(); + virtual ostream& toString(ostream& out) const; + MTGKickerRule(int _id); + const char * getMenuText() + { + return "pay kicker"; + } + virtual MTGKickerRule * clone() const; +}; + class MTGAlternativeCostRule: public MTGAbility { protected: @@ -94,7 +109,7 @@ public: { if(alternativeName.size()) return alternativeName.c_str(); - return "Pay Alternative Cost"; + return "pay alternative cost"; } virtual MTGAlternativeCostRule * clone() const; }; @@ -109,7 +124,7 @@ public: MTGBuyBackRule(int _id); const char * getMenuText() { - return "Cast And Buy Back"; + return "cast and buy back"; } virtual MTGBuyBackRule * clone() const; }; @@ -125,7 +140,7 @@ public: MTGFlashBackRule(int _id); const char * getMenuText() { - return "Flash Back"; + return "flash back"; } virtual MTGFlashBackRule * clone() const; }; @@ -140,7 +155,7 @@ public: MTGRetraceRule(int _id); const char * getMenuText() { - return "Retrace"; + return "retrace"; } virtual MTGRetraceRule * clone() const; }; @@ -156,7 +171,7 @@ public: MTGMorphCostRule(int _id); const char * getMenuText() { - return "Play Morphed"; + return "play morphed"; } virtual MTGMorphCostRule * clone() const; }; @@ -173,7 +188,7 @@ public: MTGSuspendRule(int _id); const char * getMenuText() { - suspendmenu = "Suspend"; + suspendmenu = "suspend"; //char buffer[20]; //sprintf(buffer,"-%i",card->suspendedTime); //suspendmenu.append(buffer); diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index 290fa1055..f49f5107b 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -2945,11 +2945,16 @@ void APhaseAction::Update(float dt) MTGCardInstance * _target = NULL; if(target) _target = (MTGCardInstance *) target; - if(!sAbility.size() || (!target||!_target->currentZone)) + if(!sAbility.size() || (!target||(!_target->currentZone && _target != this->source))) { this->forceDestroy = 1; return; } + else + { + while(_target->next) + _target = _target->next; + } AbilityFactory af; MTGAbility * ability = af.parseMagicLine(sAbility, abilityId, NULL, _target); diff --git a/projects/mtg/src/DuelLayers.cpp b/projects/mtg/src/DuelLayers.cpp index a0a4aa2e9..a1a844245 100644 --- a/projects/mtg/src/DuelLayers.cpp +++ b/projects/mtg/src/DuelLayers.cpp @@ -25,6 +25,7 @@ void DuelLayers::init() //Add Magic Specific Rules action->Add(NEW MTGEventBonus(-1)); action->Add(NEW MTGPutInPlayRule(-1)); + action->Add(NEW MTGKickerRule(-1)); action->Add(NEW MTGAlternativeCostRule(-1)); action->Add(NEW MTGBuyBackRule(-1)); action->Add(NEW MTGFlashBackRule(-1)); diff --git a/projects/mtg/src/GameOptions.cpp b/projects/mtg/src/GameOptions.cpp index b7d751b19..0adcc7ca8 100644 --- a/projects/mtg/src/GameOptions.cpp +++ b/projects/mtg/src/GameOptions.cpp @@ -28,6 +28,7 @@ const string Options::optionNames[] = { "maxGrade", "ASPhases", "FirstPlayer", + "KickerPay", "economic_difficulty", "transitions", "bgStyle", @@ -447,6 +448,11 @@ GameOption * GameOptions::get(int optionID) goEnum->def = OptionWhosFirst::getInstance(); go = goEnum; break; + case Options::KICKERPAYMENT: + goEnum = NEW GameOptionEnum(); + goEnum->def = OptionKicker::getInstance(); + go = goEnum; + break; case Options::KEY_BINDINGS: go = NEW GameOptionKeyBindings(); break; @@ -940,7 +946,13 @@ OptionEconDifficulty::OptionEconDifficulty() mDef.values.push_back(EnumDefinition::assoc(Constants::ECON_EASY, "Easy")); } ; - +OptionKicker OptionKicker::mDef; +OptionKicker::OptionKicker() +{ + mDef.values.push_back(EnumDefinition::assoc(Constants::KICKER_ALWAYS, "Always Pay")); + mDef.values.push_back(EnumDefinition::assoc(Constants::KICKER_CHOICE, "Offer Choice")); +} +; //GameOptionAward GameOptionAward::GameOptionAward() { diff --git a/projects/mtg/src/GameStateDuel.cpp b/projects/mtg/src/GameStateDuel.cpp index efb9a3bc6..0b7d68790 100644 --- a/projects/mtg/src/GameStateDuel.cpp +++ b/projects/mtg/src/GameStateDuel.cpp @@ -561,7 +561,6 @@ void GameStateDuel::Render() { case DUEL_STATE_END: { - JRenderer * r = JRenderer::GetInstance(); r->FillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, ARGB(200,0,0,0)); credits->Render(); #ifdef TESTSUITE diff --git a/projects/mtg/src/GameStateOptions.cpp b/projects/mtg/src/GameStateOptions.cpp index 448130462..438e92961 100644 --- a/projects/mtg/src/GameStateOptions.cpp +++ b/projects/mtg/src/GameStateOptions.cpp @@ -105,6 +105,10 @@ void GameStateOptions::Start() WDecoEnum * oFirstPlayer = NEW WDecoEnum(NEW OptionInteger(Options::FIRSTPLAYER, "First Turn Player", Constants::WHO_R, 1, Constants::WHO_P, "", Constants::WHO_P)); optionsList->Add(oFirstPlayer); + + WDecoEnum * oKickerPay = NEW WDecoEnum(NEW OptionInteger(Options::KICKERPAYMENT, "Kicker Cost", Constants::KICKER_CHOICE, 1, + Constants::KICKER_ALWAYS, "", Constants::KICKER_ALWAYS)); + optionsList->Add(oKickerPay); optionsList = NEW WGuiKeyBinder("Key Bindings", this); optionsTabs->Add(optionsList); diff --git a/projects/mtg/src/GuiAvatars.cpp b/projects/mtg/src/GuiAvatars.cpp index c5ca8bfd6..eaa44a92a 100644 --- a/projects/mtg/src/GuiAvatars.cpp +++ b/projects/mtg/src/GuiAvatars.cpp @@ -11,8 +11,9 @@ GuiAvatars::GuiAvatars() : active(NULL) { Add(self = NEW GuiAvatar(SCREEN_WIDTH, SCREEN_HEIGHT, false, GameObserver::GetInstance()->players[0], GuiAvatar::BOTTOM_RIGHT, this)); - Add(selfGraveyard = NEW GuiGraveyard(SCREEN_WIDTH - GuiAvatar::Width - GuiGameZone::Width / 2 - 5, SCREEN_HEIGHT - GuiAvatar::Height - 5, false, GameObserver::GetInstance()->players[0], this)); - Add(selfLibrary = NEW GuiLibrary(SCREEN_WIDTH - GuiAvatar::Width - GuiGameZone::Width / 2 - 5, SCREEN_HEIGHT - GuiAvatar::Height - 5 + GuiGameZone::Height + 5, false, GameObserver::GetInstance()->players[0], this)); + self->zoom = 0.9f; + Add(selfGraveyard = NEW GuiGraveyard(SCREEN_WIDTH - GuiAvatar::Width - GuiGameZone::Width / 2 - 11, SCREEN_HEIGHT - GuiAvatar::Height - 1, false, GameObserver::GetInstance()->players[0], this)); + Add(selfLibrary = NEW GuiLibrary(SCREEN_WIDTH - GuiAvatar::Width - GuiGameZone::Width / 2 - 11, SCREEN_HEIGHT - GuiAvatar::Height - 5 + GuiGameZone::Height + 5, false, GameObserver::GetInstance()->players[0], this)); Add(opponent = NEW GuiAvatar(0, 0, false, GameObserver::GetInstance()->players[1], GuiAvatar::TOP_LEFT, this)); opponent->zoom = 0.9f; @@ -20,9 +21,9 @@ GuiAvatars::GuiAvatars() : Add(opponentHand = NEW GuiOpponentHand(-30 + GuiAvatar::Width * 1.2 - GuiGameZone::Width / 2, 35 + GuiGameZone::Height - 10, false, GameObserver::GetInstance()->players[1], this)); //opponenthandveiwends - Add(opponentGraveyard = NEW GuiGraveyard(5 + GuiAvatar::Width * 1.2 - GuiGameZone::Width / 2, 5, false, + Add(opponentGraveyard = NEW GuiGraveyard(5 + GuiAvatar::Width * 1.4 - GuiGameZone::Width / 2, 5, false, GameObserver::GetInstance()->players[1], this)); - Add(opponentLibrary = NEW GuiLibrary(5 + GuiAvatar::Width * 1.2 - GuiGameZone::Width / 2, 5 + GuiGameZone::Height + 5, false, + Add(opponentLibrary = NEW GuiLibrary(5 + GuiAvatar::Width * 1.4 - GuiGameZone::Width / 2, 5 + GuiGameZone::Height + 5, false, GameObserver::GetInstance()->players[1], this)); CardSelectorSingleton::Instance()->Add(self); @@ -77,7 +78,7 @@ void GuiAvatars::Deactivate(PlayGuiObject* c) else if ((selfGraveyard == c) || (selfLibrary == c) || (self == c)) { selfGraveyard->alpha = selfLibrary->alpha = 0; - self->zoom = 0.3f; + self->zoom = 0.5f; active = NULL; } } @@ -153,7 +154,7 @@ void GuiAvatars::Render() } else if (self == active) { - r->FillRect(self->actX - w * self->actZ, self->actY - h * self->actZ, w * self->actZ, h * self->actZ, ARGB(200,0,0,0)); + r->FillRect(self->actX - w * self->actZ -4.5, self->actY - h * self->actZ, w * self->actZ, h * self->actZ, ARGB(200,0,0,0)); } GuiLayer::Render(); diff --git a/projects/mtg/src/MTGRules.cpp b/projects/mtg/src/MTGRules.cpp index 54ecfc893..aaaa6429b 100644 --- a/projects/mtg/src/MTGRules.cpp +++ b/projects/mtg/src/MTGRules.cpp @@ -397,6 +397,17 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card) ManaCost * previousManaPool = NEW ManaCost(player->getManaPool()); int payResult = player->getManaPool()->pay(card->getManaCost()); + if (card->getManaCost()->kicker && OptionKicker::KICKER_ALWAYS == options[Options::KICKERPAYMENT].number) + { + ManaCost * withKickerCost= NEW ManaCost(card->getManaCost()); + withKickerCost->add(withKickerCost->kicker); + if (previousManaPool->canAfford(withKickerCost)) + { + player->getManaPool()->pay(card->getManaCost()->kicker); + payResult = ManaCost::MANA_PAID_WITH_KICKER; + } + delete withKickerCost; + } card->getManaCost()->doPayExtra(); ManaCost * spellCost = previousManaPool->Diff(player->getManaPool()); @@ -462,8 +473,133 @@ MTGPutInPlayRule * MTGPutInPlayRule::clone() const return a; } -//cast from anywhere possible with this?? +//kicker +MTGKickerRule::MTGKickerRule(int _id) : +MTGPutInPlayRule(_id) +{ + aType = MTGAbility::PUT_INTO_PLAY_WITH_KICKER; +} +int MTGKickerRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana) +{ + if(OptionKicker::KICKER_ALWAYS == options[Options::KICKERPAYMENT].number) + return 0; + Player * player = game->currentlyActing(); + ManaCost * kicker = card->getManaCost()->kicker; + if(!kicker) + { + SAFE_DELETE(kicker); + return 0; + } + ManaCost * playerMana = player->getManaPool(); + ManaCost * withKickerCost= NEW ManaCost(card->getManaCost()); + withKickerCost->add(withKickerCost->kicker); + if(!playerMana->canAfford(withKickerCost)) + { + delete withKickerCost; + return 0; + } + delete withKickerCost; + + + return 1; +} + +int MTGKickerRule::reactToClick(MTGCardInstance * card) +{ + if(!isReactingToClick(card, NULL)) + return 0; + + Player * player = game->currentlyActing(); + ManaCost * withKickerCost= NEW ManaCost(card->getManaCost());//using pointers here alters the real cost of the card. + withKickerCost->add(withKickerCost->kicker); + card->paymenttype = MTGAbility::PUT_INTO_PLAY_WITH_KICKER; + if (withKickerCost->isExtraPaymentSet()) + { + if (!game->targetListIsSet(card)) + { + delete withKickerCost; + return 0; + } + } + else + { + withKickerCost->setExtraCostsAction(this, card); + game->mExtraPayment = withKickerCost->extraCosts; + delete withKickerCost; + return 0; + } + + ManaCost * previousManaPool = NEW ManaCost(player->getManaPool()); + int payResult = player->getManaPool()->pay(withKickerCost); + withKickerCost->doPayExtra(); + ManaCost * spellCost = previousManaPool->Diff(player->getManaPool()); + delete withKickerCost; + delete previousManaPool; + if (card->isLand()) + { + MTGCardInstance * copy = player->game->putInZone(card, player->game->hand, player->game->temp); + Spell * spell = NEW Spell(0,copy,NULL,NULL, ManaCost::MANA_PAID_WITH_KICKER); + spell->resolve(); + delete spellCost; + delete spell; + } + else + { + Spell * spell = NULL; + MTGCardInstance * copy = player->game->putInZone(card, player->game->hand, player->game->stack); + if (game->targetChooser) + { + spell = game->mLayers->stackLayer()->addSpell(copy, game->targetChooser, spellCost, ManaCost::MANA_PAID_WITH_KICKER, 0); + game->targetChooser = NULL; + } + else + { + spell = game->mLayers->stackLayer()->addSpell(copy, NULL, spellCost, ManaCost::MANA_PAID_WITH_KICKER, 0); + } + + if (card->has(Constants::STORM)) + { + int storm = player->game->stack->seenThisTurn("*", Constants::CAST_ALL) + player->opponent()->game->stack->seenThisTurn("*", Constants::CAST_ALL); + ManaCost * stormSpellCost = player->getManaPool(); + for (int i = storm; i > 1; i--) + { + spell = game->mLayers->stackLayer()->addSpell(copy, NULL, stormSpellCost, ManaCost::MANA_PAID_WITH_KICKER, 1); + + } + }//end of storm + if (!card->has(Constants::STORM)) + { + copy->X = spell->computeX(copy); + copy->XX = spell->computeXX(copy); + } + } + + return 1; +} + +int MTGKickerRule::testDestroy() +{ + return 0; +} + +ostream& MTGKickerRule::toString(ostream& out) const +{ + out << "MTGKickerRule ::: ("; + return MTGAbility::toString(out) << ")"; +} + +MTGKickerRule * MTGKickerRule::clone() const +{ + MTGKickerRule * a = NEW MTGKickerRule(*this); + a->isClone = 1; + return a; +} + + + + +//cast from anywhere possible with this?? //Alternative cost rules //------------------------------------------------------------------------- //------------------------------------------------------------------------- diff --git a/projects/mtg/src/ManaCost.cpp b/projects/mtg/src/ManaCost.cpp index b001126fb..f7b3f0f50 100644 --- a/projects/mtg/src/ManaCost.cpp +++ b/projects/mtg/src/ManaCost.cpp @@ -597,20 +597,6 @@ int ManaCost::pay(ManaCost * _cost) int result = MANA_PAID; ManaCost * toPay = NEW ManaCost(); toPay->copy(_cost); - - if (toPay->kicker) - { - toPay->add(toPay->kicker); - if (!canAfford(toPay)) - { - toPay->copy(_cost); - } - else - { - result = MANA_PAID_WITH_KICKER; - } - } - ManaCost * diff = Diff(toPay); for (int i = 0; i < Constants::MTG_NB_COLORS; i++) { diff --git a/projects/mtg/src/SimpleMenu.cpp b/projects/mtg/src/SimpleMenu.cpp index 4e0b31a01..84f5d888f 100644 --- a/projects/mtg/src/SimpleMenu.cpp +++ b/projects/mtg/src/SimpleMenu.cpp @@ -122,7 +122,8 @@ void SimpleMenu::drawVertPole(float x, float y, float height) void SimpleMenu::Render() { - WFont * titleFont = WResourceManager::Instance()->GetWFont(Fonts::SMALLFACE_FONT); + WFont * titleFont = WResourceManager::Instance()->GetWFont(fontId); + titleFont->SetColor(ARGB(250,255,255,255));//reseting color on passes as this is a shared font now. WFont * mFont = WResourceManager::Instance()->GetWFont(fontId); if (0 == mWidth) {