added support for alternative casting cost, evoke, added support for phantom cycle,hydras, added support for exile/bounce as casting cost
This commit is contained in:
@@ -88,6 +88,7 @@ class Spell: public Interruptible {
|
|||||||
int resolve();
|
int resolve();
|
||||||
void Render();
|
void Render();
|
||||||
bool kickerWasPaid();
|
bool kickerWasPaid();
|
||||||
|
bool AlternativeWasPaid();
|
||||||
const string getDisplayName() const;
|
const string getDisplayName() const;
|
||||||
virtual ostream& toString(ostream& out) const;
|
virtual ostream& toString(ostream& out) const;
|
||||||
MTGCardInstance * getNextCardTarget(MTGCardInstance * previous = 0);
|
MTGCardInstance * getNextCardTarget(MTGCardInstance * previous = 0);
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ public:
|
|||||||
intValue = target->getManaCost()->getConvertedCost();
|
intValue = target->getManaCost()->getConvertedCost();
|
||||||
}else if (s == "lifetotal"){
|
}else if (s == "lifetotal"){
|
||||||
intValue = target->controller()->life;
|
intValue = target->controller()->life;
|
||||||
|
}else if (s == "sunburst"){
|
||||||
|
intValue = target->costAmount;
|
||||||
}else if (s == "odcount"){
|
}else if (s == "odcount"){
|
||||||
intValue = target->controller()->opponent()->damageCount;
|
intValue = target->controller()->opponent()->damageCount;
|
||||||
}else if (s == "opponentlifetotal"){
|
}else if (s == "opponentlifetotal"){
|
||||||
|
|||||||
@@ -82,6 +82,32 @@ public:
|
|||||||
virtual int setSource(MTGCardInstance * _source);
|
virtual int setSource(MTGCardInstance * _source);
|
||||||
virtual TapTargetCost * clone() const;
|
virtual TapTargetCost * clone() const;
|
||||||
};
|
};
|
||||||
|
//exile as cost
|
||||||
|
class ExileTargetCost: public ExtraCost{
|
||||||
|
public:
|
||||||
|
MTGCardInstance * target;
|
||||||
|
ExileTargetCost(TargetChooser *_tc = NULL);
|
||||||
|
virtual int setPayment(MTGCardInstance * card);
|
||||||
|
virtual int isPaymentSet();
|
||||||
|
virtual int canPay();
|
||||||
|
virtual int doPay();
|
||||||
|
virtual void Render();
|
||||||
|
virtual int setSource(MTGCardInstance * _source);
|
||||||
|
virtual ExileTargetCost * clone() const;
|
||||||
|
};
|
||||||
|
//bounce cost
|
||||||
|
class BounceTargetCost: public ExtraCost{
|
||||||
|
public:
|
||||||
|
MTGCardInstance * target;
|
||||||
|
BounceTargetCost(TargetChooser *_tc = NULL);
|
||||||
|
virtual int setPayment(MTGCardInstance * card);
|
||||||
|
virtual int isPaymentSet();
|
||||||
|
virtual int canPay();
|
||||||
|
virtual int doPay();
|
||||||
|
virtual void Render();
|
||||||
|
virtual int setSource(MTGCardInstance * _source);
|
||||||
|
virtual BounceTargetCost * clone() const;
|
||||||
|
};
|
||||||
|
|
||||||
class CounterCost: public ExtraCost{
|
class CounterCost: public ExtraCost{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ class MTGAbility: public ActionElement{
|
|||||||
int oneShot;
|
int oneShot;
|
||||||
int forceDestroy;
|
int forceDestroy;
|
||||||
ManaCost * cost;
|
ManaCost * cost;
|
||||||
|
ManaCost * alternative;
|
||||||
|
|
||||||
Targetable * target;
|
Targetable * target;
|
||||||
int aType;
|
int aType;
|
||||||
MTGCardInstance * source;
|
MTGCardInstance * source;
|
||||||
|
|||||||
@@ -44,9 +44,11 @@ class MTGCardInstance: public CardPrimitive, public MTGCard, public Damageable {
|
|||||||
MTGGameZone * currentZone;
|
MTGGameZone * currentZone;
|
||||||
Pos* view;
|
Pos* view;
|
||||||
int X;
|
int X;
|
||||||
|
int costAmount;
|
||||||
int regenerateTokens;
|
int regenerateTokens;
|
||||||
int isToken;
|
int isToken;
|
||||||
int stillInUse();
|
int stillInUse();
|
||||||
|
int getCostAmount();
|
||||||
Player * lastController;
|
Player * lastController;
|
||||||
MTGGameZone * getCurrentZone();
|
MTGGameZone * getCurrentZone();
|
||||||
MTGGameZone * previousZone;
|
MTGGameZone * previousZone;
|
||||||
|
|||||||
@@ -107,8 +107,12 @@ class Constants
|
|||||||
POISONDAMAGE = 49,
|
POISONDAMAGE = 49,
|
||||||
POISONTWODAMAGE = 50,
|
POISONTWODAMAGE = 50,
|
||||||
POISONTHREEDAMAGE = 51,
|
POISONTHREEDAMAGE = 51,
|
||||||
|
PHANTOM = 52,
|
||||||
|
COUNTERASDAMAGE = 53,
|
||||||
|
VIGOR = 54,
|
||||||
|
CHANGELING = 55,
|
||||||
|
|
||||||
NB_BASIC_ABILITIES = 52,
|
NB_BASIC_ABILITIES = 56,
|
||||||
|
|
||||||
|
|
||||||
RARITY_S = 'S', //Special Rarity
|
RARITY_S = 'S', //Special Rarity
|
||||||
|
|||||||
@@ -160,6 +160,8 @@ class MTGPlayerCards {
|
|||||||
void resetLibrary();
|
void resetLibrary();
|
||||||
void initDeck(MTGDeck * deck);
|
void initDeck(MTGDeck * deck);
|
||||||
MTGCardInstance * putInGraveyard(MTGCardInstance * card);
|
MTGCardInstance * putInGraveyard(MTGCardInstance * card);
|
||||||
|
MTGCardInstance * putInExile(MTGCardInstance * card);
|
||||||
|
MTGCardInstance * putInHand(MTGCardInstance * card);
|
||||||
MTGCardInstance * putInZone(MTGCardInstance * card, MTGGameZone * from, MTGGameZone * to);
|
MTGCardInstance * putInZone(MTGCardInstance * card, MTGGameZone * from, MTGGameZone * to);
|
||||||
int isInPlay(MTGCardInstance * card);
|
int isInPlay(MTGCardInstance * card);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,10 +22,12 @@ class ManaCost{
|
|||||||
public:
|
public:
|
||||||
enum{
|
enum{
|
||||||
MANA_PAID = 1,
|
MANA_PAID = 1,
|
||||||
MANA_PAID_WITH_KICKER = 2
|
MANA_PAID_WITH_KICKER = 2,
|
||||||
|
MANA_PAID_WITH_ALTERNATIVE = 3
|
||||||
};
|
};
|
||||||
ExtraCosts * extraCosts;
|
ExtraCosts * extraCosts;
|
||||||
ManaCost * kicker;
|
ManaCost * kicker;
|
||||||
|
ManaCost * alternative;
|
||||||
static ManaCost * parseManaCost(string value, ManaCost * _manacost = NULL, MTGCardInstance * c = NULL);
|
static ManaCost * parseManaCost(string value, ManaCost * _manacost = NULL, MTGCardInstance * c = NULL);
|
||||||
virtual void init();
|
virtual void init();
|
||||||
void x();
|
void x();
|
||||||
|
|||||||
@@ -166,6 +166,10 @@ bool Spell::kickerWasPaid(){
|
|||||||
return (payResult == ManaCost::MANA_PAID_WITH_KICKER);
|
return (payResult == ManaCost::MANA_PAID_WITH_KICKER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Spell::AlternativeWasPaid(){
|
||||||
|
return (payResult == ManaCost::MANA_PAID_WITH_ALTERNATIVE);
|
||||||
|
}
|
||||||
|
|
||||||
const string Spell::getDisplayName() const {
|
const string Spell::getDisplayName() const {
|
||||||
return source->getName();
|
return source->getName();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,28 @@ int Damage::resolve(){
|
|||||||
if (target->type_as_damageable == DAMAGEABLE_MTGCARDINSTANCE){
|
if (target->type_as_damageable == DAMAGEABLE_MTGCARDINSTANCE){
|
||||||
MTGCardInstance * _target = (MTGCardInstance *)target;
|
MTGCardInstance * _target = (MTGCardInstance *)target;
|
||||||
if ((_target)->protectedAgainst(source)) damage = 0;
|
if ((_target)->protectedAgainst(source)) damage = 0;
|
||||||
|
//rulings = 10/4/2004 The damage prevention ability works even if it has no counters, as long as some effect keeps its toughness above zero.
|
||||||
|
//these creature are essentially immune to damage. however 0/-1 effects applied through lords or counters can kill them.
|
||||||
|
if ((_target)->has(Constants::PHANTOM)) {
|
||||||
|
damage = 0;
|
||||||
|
(_target)->counters->removeCounter(1,1);
|
||||||
|
}
|
||||||
|
if ((_target)->has(Constants::COUNTERASDAMAGE)) {
|
||||||
|
for (int i = 0; i < damage; i++){
|
||||||
|
for (int i = damage; i > 0; i--){
|
||||||
|
(_target)->counters->addCounter(-1,-1);
|
||||||
|
}
|
||||||
|
damage = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((_target)->has(Constants::VIGOR)){
|
||||||
|
for (int i = 0; i < damage; i++){
|
||||||
|
for (int i = damage; i > 0; i--){
|
||||||
|
(_target)->counters->addCounter(1,1);
|
||||||
|
}
|
||||||
|
damage = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!damage){
|
if (!damage){
|
||||||
state = RESOLVED_NOK;
|
state = RESOLVED_NOK;
|
||||||
delete (e);
|
delete (e);
|
||||||
|
|||||||
@@ -140,6 +140,133 @@ void TapTargetCost::Render(){
|
|||||||
mFont->DrawString(buffer, 20 ,20, JGETEXT_LEFT);
|
mFont->DrawString(buffer, 20 ,20, JGETEXT_LEFT);
|
||||||
}
|
}
|
||||||
//endtaptargetcost
|
//endtaptargetcost
|
||||||
|
|
||||||
|
//exile as cost
|
||||||
|
ExileTargetCost * ExileTargetCost::clone() const{
|
||||||
|
ExileTargetCost * ec = NEW ExileTargetCost(*this);
|
||||||
|
if (tc) ec->tc = tc->clone();
|
||||||
|
return ec;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ExileTargetCost::ExileTargetCost(TargetChooser *_tc):ExtraCost(_tc){
|
||||||
|
if (tc) tc->targetter = NULL; //tapping targets is not targetting, protections do not apply
|
||||||
|
target = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ExileTargetCost::setSource(MTGCardInstance * card){
|
||||||
|
ExtraCost::setSource(card);
|
||||||
|
if (tc) tc->targetter = NULL; //Tapping targets is not targetting, protections do not apply
|
||||||
|
if (!tc) target = card;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ExileTargetCost::setPayment(MTGCardInstance * card){
|
||||||
|
if (tc) {
|
||||||
|
int result = tc->addTarget(card);
|
||||||
|
if (result) {
|
||||||
|
target = card;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ExileTargetCost::isPaymentSet(){
|
||||||
|
if (target) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ExileTargetCost::canPay(){
|
||||||
|
//tap target does not have any additional restrictions.
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ExileTargetCost::doPay(){
|
||||||
|
MTGCardInstance * _target = (MTGCardInstance *) target;
|
||||||
|
if(target){
|
||||||
|
target->controller()->game->putInExile(target);
|
||||||
|
target = NULL;
|
||||||
|
if (tc) tc->initTargets();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExileTargetCost::Render(){
|
||||||
|
//TODO : real stuff
|
||||||
|
WFont * mFont = resources.GetWFont(Constants::MAIN_FONT);
|
||||||
|
mFont->SetScale(DEFAULT_MAIN_FONT_SCALE);
|
||||||
|
mFont->SetColor(ARGB(255,255,255,255));
|
||||||
|
char buffer[200];
|
||||||
|
sprintf(buffer, "%s", _("Exile Target").c_str());
|
||||||
|
mFont->DrawString(buffer, 20 ,20, JGETEXT_LEFT);
|
||||||
|
}
|
||||||
|
//endExiletargetcost
|
||||||
|
//------------------------------------------------------------
|
||||||
|
//Bounce as cost
|
||||||
|
BounceTargetCost * BounceTargetCost::clone() const{
|
||||||
|
BounceTargetCost * ec = NEW BounceTargetCost(*this);
|
||||||
|
if (tc) ec->tc = tc->clone();
|
||||||
|
return ec;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BounceTargetCost::BounceTargetCost(TargetChooser *_tc):ExtraCost(_tc){
|
||||||
|
if (tc) tc->targetter = NULL; //tapping targets is not targetting, protections do not apply
|
||||||
|
target = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int BounceTargetCost::setSource(MTGCardInstance * card){
|
||||||
|
ExtraCost::setSource(card);
|
||||||
|
if (tc) tc->targetter = NULL; //Tapping targets is not targetting, protections do not apply
|
||||||
|
if (!tc) target = card;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int BounceTargetCost::setPayment(MTGCardInstance * card){
|
||||||
|
if (tc) {
|
||||||
|
int result = tc->addTarget(card);
|
||||||
|
if (result) {
|
||||||
|
target = card;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int BounceTargetCost::isPaymentSet(){
|
||||||
|
if (target) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int BounceTargetCost::canPay(){
|
||||||
|
//tap target does not have any additional restrictions.
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int BounceTargetCost::doPay(){
|
||||||
|
MTGCardInstance * _target = (MTGCardInstance *) target;
|
||||||
|
if(target){
|
||||||
|
target->controller()->game->putInHand(target);
|
||||||
|
target = NULL;
|
||||||
|
if (tc) tc->initTargets();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BounceTargetCost::Render(){
|
||||||
|
//TODO : real stuff
|
||||||
|
WFont * mFont = resources.GetWFont(Constants::MAIN_FONT);
|
||||||
|
mFont->SetScale(DEFAULT_MAIN_FONT_SCALE);
|
||||||
|
mFont->SetColor(ARGB(255,255,255,255));
|
||||||
|
char buffer[200];
|
||||||
|
sprintf(buffer, "%s", _("Return Target to Hand").c_str());
|
||||||
|
mFont->DrawString(buffer, 20 ,20, JGETEXT_LEFT);
|
||||||
|
}
|
||||||
|
//endbouncetargetcost
|
||||||
|
//------------------------------------------------------------
|
||||||
SacrificeCost * SacrificeCost::clone() const{
|
SacrificeCost * SacrificeCost::clone() const{
|
||||||
SacrificeCost * ec = NEW SacrificeCost(*this);
|
SacrificeCost * ec = NEW SacrificeCost(*this);
|
||||||
if (tc) ec->tc = tc->clone();
|
if (tc) ec->tc = tc->clone();
|
||||||
|
|||||||
@@ -343,6 +343,16 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//alternative cost
|
||||||
|
found = s.find("alternative ");
|
||||||
|
if (found == 0){
|
||||||
|
if (spell && spell->AlternativeWasPaid()){
|
||||||
|
string s1 = s.substr(found+7);
|
||||||
|
return parseMagicLine(s1,id,spell, card);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
//When...comes into play, you may...
|
//When...comes into play, you may...
|
||||||
found = s.find("may ");
|
found = s.find("may ");
|
||||||
if (found == 0){
|
if (found == 0){
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ void MTGCardInstance::initMTGCI(){
|
|||||||
next = NULL;
|
next = NULL;
|
||||||
lastController = NULL;
|
lastController = NULL;
|
||||||
regenerateTokens = 0;
|
regenerateTokens = 0;
|
||||||
|
costAmount = 0;
|
||||||
blocked = false;
|
blocked = false;
|
||||||
currentZone = NULL;
|
currentZone = NULL;
|
||||||
data = this; //an MTGCardInstance point to itself for data, allows to update it without killing the underlying database item
|
data = this; //an MTGCardInstance point to itself for data, allows to update it without killing the underlying database item
|
||||||
@@ -296,6 +297,10 @@ int MTGCardInstance::hasSummoningSickness(){
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int MTGCardInstance::getCostAmount(){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
MTGCardInstance * MTGCardInstance::changeController(Player * newController){
|
MTGCardInstance * MTGCardInstance::changeController(Player * newController){
|
||||||
Player * originalOwner = controller();
|
Player * originalOwner = controller();
|
||||||
if (originalOwner == newController) return this;
|
if (originalOwner == newController) return this;
|
||||||
|
|||||||
@@ -108,6 +108,15 @@ int MTGAllCards::processConfLine(string &s, MTGCard *card, CardPrimitive * primi
|
|||||||
cost->kicker = ManaCost::parseManaCost(value);
|
cost->kicker = ManaCost::parseManaCost(value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'o': //othercost
|
||||||
|
if (!primitive) primitive = NEW CardPrimitive();
|
||||||
|
if (ManaCost * cost = primitive->getManaCost())
|
||||||
|
{
|
||||||
|
string value = val;
|
||||||
|
std::transform(value.begin(), value.end(), value.begin(), ::tolower);
|
||||||
|
cost->alternative = ManaCost::parseManaCost(value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case 'i': //id
|
case 'i': //id
|
||||||
if (!card) card = NEW MTGCard();
|
if (!card) card = NEW MTGCard();
|
||||||
|
|||||||
@@ -60,7 +60,10 @@ const char* Constants::MTGBasicAbilities[] = {
|
|||||||
"poisondamage",
|
"poisondamage",
|
||||||
"poisontwodamage",
|
"poisontwodamage",
|
||||||
"poisonthreedamage",
|
"poisonthreedamage",
|
||||||
|
"phantom",//prevents damage and remove 1 +1/+1 counter
|
||||||
|
"counterasdamage",//source takes damage in the form of -1/-1 counters.
|
||||||
|
"vigor",//instead of taking damage the source gains +1/+1 counters
|
||||||
|
"changeling",//this card is every creature type at all times
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -125,6 +125,38 @@ MTGCardInstance * MTGPlayerCards::putInGraveyard(MTGCardInstance * card){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MTGCardInstance * MTGPlayerCards::putInExile(MTGCardInstance * card){
|
||||||
|
MTGCardInstance * copy = NULL;
|
||||||
|
MTGRemovedFromGame * exile = card->owner->game->exile;
|
||||||
|
if (inPlay->hasCard(card)){
|
||||||
|
copy = putInZone(card,inPlay, exile);
|
||||||
|
}else if (stack->hasCard(card)){
|
||||||
|
copy = putInZone(card,stack, exile);
|
||||||
|
}
|
||||||
|
if(graveyard->hasCard(card)){
|
||||||
|
copy = putInZone(card,graveyard, exile);
|
||||||
|
}else{
|
||||||
|
copy = putInZone(card,hand, exile);
|
||||||
|
}
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
MTGCardInstance * MTGPlayerCards::putInHand(MTGCardInstance * card){
|
||||||
|
MTGCardInstance * copy = NULL;
|
||||||
|
MTGHand * hand = card->owner->game->hand;
|
||||||
|
if (inPlay->hasCard(card)){
|
||||||
|
copy = putInZone(card,inPlay, hand);
|
||||||
|
}else if (stack->hasCard(card)){
|
||||||
|
copy = putInZone(card,stack, hand);
|
||||||
|
}
|
||||||
|
if(graveyard->hasCard(card)){
|
||||||
|
copy = putInZone(card,graveyard, hand);
|
||||||
|
}else{
|
||||||
|
copy = putInZone(card,hand, hand);
|
||||||
|
}
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone * from, MTGGameZone * to){
|
MTGCardInstance * MTGPlayerCards::putInZone(MTGCardInstance * card, MTGGameZone * from, MTGGameZone * to){
|
||||||
MTGCardInstance * copy = NULL;
|
MTGCardInstance * copy = NULL;
|
||||||
GameObserver *g = GameObserver::GetInstance();
|
GameObserver *g = GameObserver::GetInstance();
|
||||||
|
|||||||
@@ -31,12 +31,18 @@ int cardsinhand = game->players[0]->game->hand->nb_cards;
|
|||||||
}else if ((card->hasType("instant")) || card->has(Constants::FLASH) || (player == currentPlayer && !game->isInterrupting && (game->currentGamePhase == Constants::MTG_PHASE_FIRSTMAIN || game->currentGamePhase == Constants::MTG_PHASE_SECONDMAIN))){
|
}else if ((card->hasType("instant")) || card->has(Constants::FLASH) || (player == currentPlayer && !game->isInterrupting && (game->currentGamePhase == Constants::MTG_PHASE_FIRSTMAIN || game->currentGamePhase == Constants::MTG_PHASE_SECONDMAIN))){
|
||||||
ManaCost * playerMana = player->getManaPool();
|
ManaCost * playerMana = player->getManaPool();
|
||||||
ManaCost * cost = card->getManaCost();
|
ManaCost * cost = card->getManaCost();
|
||||||
|
ManaCost * alternative = card->getManaCost()->alternative;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
cost->Dump();
|
cost->Dump();
|
||||||
#endif
|
#endif
|
||||||
if (playerMana->canAfford(cost)){
|
|
||||||
|
if(alternative && playerMana->canAfford(alternative)){
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (playerMana->canAfford(cost)){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -44,6 +50,9 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card){
|
|||||||
if (!isReactingToClick(card)) return 0;
|
if (!isReactingToClick(card)) return 0;
|
||||||
Player * player = game->currentlyActing();
|
Player * player = game->currentlyActing();
|
||||||
ManaCost * cost = card->getManaCost();
|
ManaCost * cost = card->getManaCost();
|
||||||
|
ManaCost * alternative = card->getManaCost()->alternative;
|
||||||
|
ManaCost * playerMana = player->getManaPool();
|
||||||
|
//this handles extra cost payments at the moment a card is played.
|
||||||
if (cost->isExtraPaymentSet()){
|
if (cost->isExtraPaymentSet()){
|
||||||
if (!game->targetListIsSet(card)){
|
if (!game->targetListIsSet(card)){
|
||||||
return 0;
|
return 0;
|
||||||
@@ -53,10 +62,34 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card){
|
|||||||
game->waitForExtraPayment = cost->extraCosts;
|
game->waitForExtraPayment = cost->extraCosts;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//as long as you dont have enough mana to pay the real cost, and the alternative contains extra cost, add extras
|
||||||
|
if(!playerMana->canAfford(cost) && playerMana->canAfford(alternative)){
|
||||||
|
if (cost->alternative->isExtraPaymentSet()){
|
||||||
|
if (!game->targetListIsSet(card)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
cost->alternative->setExtraCostsAction(this, card);
|
||||||
|
game->waitForExtraPayment = cost->alternative->extraCosts;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
ManaCost * previousManaPool = NEW ManaCost(player->getManaPool());
|
ManaCost * previousManaPool = NEW ManaCost(player->getManaPool());
|
||||||
int payResult = player->getManaPool()->pay(card->getManaCost());
|
int payResult = player->getManaPool()->pay(card->getManaCost());
|
||||||
card->getManaCost()->doPayExtra();
|
card->getManaCost()->doPayExtra();
|
||||||
|
|
||||||
|
|
||||||
|
//if alternative has a extra payment thats set, this code pays it.the if statement is 100% needed as it would cause a crash on cards that dont have the alternative cost.
|
||||||
|
if(alternative){
|
||||||
|
card->getManaCost()->alternative->doPayExtra();}
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
ManaCost * spellCost = previousManaPool->Diff(player->getManaPool());
|
ManaCost * spellCost = previousManaPool->Diff(player->getManaPool());
|
||||||
|
|
||||||
delete previousManaPool;
|
delete previousManaPool;
|
||||||
if (card->hasType("land")){
|
if (card->hasType("land")){
|
||||||
MTGCardInstance * copy = player->game->putInZone(card, player->game->hand, player->game->temp);
|
MTGCardInstance * copy = player->game->putInZone(card, player->game->hand, player->game->temp);
|
||||||
@@ -131,7 +164,7 @@ int MTGAttackRule::receiveEvent(WEvent *e){
|
|||||||
for (int i= 0; i < z->nb_cards; i++){
|
for (int i= 0; i < z->nb_cards; i++){
|
||||||
MTGCardInstance * card = z->cards[i];
|
MTGCardInstance * card = z->cards[i];
|
||||||
if (!card->isAttacker() && card->has(Constants::MUSTATTACK)) reactToClick(card);
|
if (!card->isAttacker() && card->has(Constants::MUSTATTACK)) reactToClick(card);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,7 +249,6 @@ int MTGBlockRule::isReactingToClick(MTGCardInstance * card, ManaCost * mana){
|
|||||||
int MTGBlockRule::reactToClick(MTGCardInstance * card){
|
int MTGBlockRule::reactToClick(MTGCardInstance * card){
|
||||||
if (!isReactingToClick(card)) return 0;
|
if (!isReactingToClick(card)) return 0;
|
||||||
MTGCardInstance * currentOpponent = card->isDefenser();
|
MTGCardInstance * currentOpponent = card->isDefenser();
|
||||||
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
int candefend = 0;
|
int candefend = 0;
|
||||||
while (!result){
|
while (!result){
|
||||||
|
|||||||
@@ -79,7 +79,34 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan
|
|||||||
}
|
}
|
||||||
manaCost->addExtraCost(NEW TapTargetCost(tc));
|
manaCost->addExtraCost(NEW TapTargetCost(tc));
|
||||||
//tapcost
|
//tapcost
|
||||||
|
//exile cost
|
||||||
|
}else if (value[0] == 'e'){
|
||||||
|
//tap
|
||||||
|
OutputDebugString("Exile\n");
|
||||||
|
TargetChooserFactory tcf;
|
||||||
|
TargetChooser * tc = NULL;
|
||||||
|
size_t target_start = value.find("(");
|
||||||
|
size_t target_end = value.find(")");
|
||||||
|
if (target_start!=string::npos && target_end!=string::npos){
|
||||||
|
string target = value.substr(target_start+1, target_end-1 - target_start);
|
||||||
|
tc = tcf.createTargetChooser(target,c);
|
||||||
|
}
|
||||||
|
manaCost->addExtraCost(NEW ExileTargetCost(tc));
|
||||||
|
//---------------------------------
|
||||||
|
//bounce cost
|
||||||
|
}else if (value[0] == 'h'){
|
||||||
|
//tap
|
||||||
|
OutputDebugString("Bounce\n");
|
||||||
|
TargetChooserFactory tcf;
|
||||||
|
TargetChooser * tc = NULL;
|
||||||
|
size_t target_start = value.find("(");
|
||||||
|
size_t target_end = value.find(")");
|
||||||
|
if (target_start!=string::npos && target_end!=string::npos){
|
||||||
|
string target = value.substr(target_start+1, target_end-1 - target_start);
|
||||||
|
tc = tcf.createTargetChooser(target,c);
|
||||||
|
}
|
||||||
|
manaCost->addExtraCost(NEW BounceTargetCost(tc));
|
||||||
|
//---------------------------------
|
||||||
|
|
||||||
//life cost
|
//life cost
|
||||||
}else if (value[0] == 'l'){
|
}else if (value[0] == 'l'){
|
||||||
@@ -186,6 +213,8 @@ ManaCost::~ManaCost(){
|
|||||||
SAFE_DELETE(extraCosts);
|
SAFE_DELETE(extraCosts);
|
||||||
|
|
||||||
SAFE_DELETE(kicker);
|
SAFE_DELETE(kicker);
|
||||||
|
|
||||||
|
SAFE_DELETE(alternative);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ManaCost::x(){
|
void ManaCost::x(){
|
||||||
@@ -205,6 +234,7 @@ void ManaCost::init(){
|
|||||||
extraCosts = NULL;
|
extraCosts = NULL;
|
||||||
extraCostsIsCopy = 0;
|
extraCostsIsCopy = 0;
|
||||||
kicker = NULL;
|
kicker = NULL;
|
||||||
|
alternative = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -231,6 +261,11 @@ void ManaCost::copy(ManaCost * _manaCost){
|
|||||||
kicker = NEW ManaCost();
|
kicker = NEW ManaCost();
|
||||||
kicker->copy(_manaCost->kicker);
|
kicker->copy(_manaCost->kicker);
|
||||||
}
|
}
|
||||||
|
SAFE_DELETE(alternative);
|
||||||
|
if (_manaCost->alternative){
|
||||||
|
alternative = NEW ManaCost();
|
||||||
|
alternative->copy(_manaCost->alternative);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ManaCost::getCost(int color){
|
int ManaCost::getCost(int color){
|
||||||
@@ -334,15 +369,30 @@ int ManaCost::setExtraCostsAction(MTGAbility * action, MTGCardInstance * card){
|
|||||||
int ManaCost::pay(ManaCost * _cost){
|
int ManaCost::pay(ManaCost * _cost){
|
||||||
int result = MANA_PAID;
|
int result = MANA_PAID;
|
||||||
ManaCost * toPay = NEW ManaCost();
|
ManaCost * toPay = NEW ManaCost();
|
||||||
toPay->copy(_cost);
|
toPay->copy(_cost);
|
||||||
|
|
||||||
|
|
||||||
|
//---if you can pay the cards real cost, it is paided instead and alternative is not used.
|
||||||
|
if (toPay->alternative && canAfford(toPay->alternative) && !canAfford(_cost)){
|
||||||
|
//const char * getMenuText(){return "Put into play";}
|
||||||
|
toPay = toPay->alternative;
|
||||||
|
if (!canAfford(toPay) || canAfford(_cost)){
|
||||||
|
toPay->copy(_cost);
|
||||||
|
}
|
||||||
|
result = MANA_PAID_WITH_ALTERNATIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (toPay->kicker){
|
if (toPay->kicker){
|
||||||
toPay->add(toPay->kicker);
|
toPay->add(toPay->kicker);
|
||||||
if (!canAfford(toPay)){
|
if (!canAfford(toPay)){
|
||||||
toPay->copy(_cost);
|
toPay->copy(_cost);
|
||||||
}else{
|
}else{
|
||||||
result = MANA_PAID_WITH_KICKER;
|
result = MANA_PAID_WITH_KICKER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ManaCost * diff = Diff(toPay);
|
ManaCost * diff = Diff(toPay);
|
||||||
for (int i=0; i < Constants::MTG_NB_COLORS; i++){
|
for (int i=0; i < Constants::MTG_NB_COLORS; i++){
|
||||||
cost[i] = diff->getCost(i);
|
cost[i] = diff->getCost(i);
|
||||||
@@ -518,6 +568,7 @@ int ManaPool::pay (ManaCost * _cost){
|
|||||||
for (unsigned int i = 0; i < Constants::MTG_NB_COLORS; i++){
|
for (unsigned int i = 0; i < Constants::MTG_NB_COLORS; i++){
|
||||||
current[i] = cost[i];
|
current[i] = cost[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
int result = ManaCost::pay(_cost);
|
int result = ManaCost::pay(_cost);
|
||||||
for (unsigned int i = 0; i < Constants::MTG_NB_COLORS; i++){
|
for (unsigned int i = 0; i < Constants::MTG_NB_COLORS; i++){
|
||||||
int value = current[i] - cost[i];
|
int value = current[i] - cost[i];
|
||||||
|
|||||||
@@ -99,8 +99,6 @@ int Player::prevented(){
|
|||||||
void Player::cleanupPhase(){
|
void Player::cleanupPhase(){
|
||||||
game->inPlay->cleanupPhase();
|
game->inPlay->cleanupPhase();
|
||||||
game->graveyard->cleanupPhase();
|
game->graveyard->cleanupPhase();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ostream& operator<<(ostream& out, const Player& p)
|
ostream& operator<<(ostream& out, const Player& p)
|
||||||
|
|||||||
@@ -519,6 +519,7 @@ bool TypeTargetChooser::canTarget(Targetable * target){
|
|||||||
MTGCardInstance * card = (MTGCardInstance *) target;
|
MTGCardInstance * card = (MTGCardInstance *) target;
|
||||||
for (int i= 0; i < nbtypes; i++){
|
for (int i= 0; i < nbtypes; i++){
|
||||||
if (card->hasSubtype(types[i])) return true;
|
if (card->hasSubtype(types[i])) return true;
|
||||||
|
if (card->has(Constants::CHANGELING)) return true;
|
||||||
if (Subtypes::subtypesList->find(card->getLCName()) == types[i]) return true;
|
if (Subtypes::subtypesList->find(card->getLCName()) == types[i]) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user