Support for KLD and AER
Kaladesh & Aether Revolt
This commit is contained in:
@@ -560,6 +560,14 @@ private:
|
||||
{
|
||||
intValue = card->controller()->opponent()->raidcount;
|
||||
}
|
||||
else if (s == "pstormcount")
|
||||
{
|
||||
intValue = card->controller()->game->stack->seenThisTurn("*", Constants::CAST_ALL);
|
||||
}
|
||||
else if (s == "ostormcount")
|
||||
{
|
||||
intValue = card->controller()->opponent()->game->stack->seenThisTurn("*", Constants::CAST_ALL);
|
||||
}
|
||||
else if (s == "countallspell")
|
||||
{
|
||||
intValue = card->controller()->game->stack->seenThisTurn("*", Constants::CAST_ALL) + card->controller()->opponent()->game->stack->seenThisTurn("*", Constants::CAST_ALL);
|
||||
@@ -4514,6 +4522,19 @@ public:
|
||||
AAAlterPoison * clone() const;
|
||||
~AAAlterPoison();
|
||||
};
|
||||
//Energy Counter
|
||||
class AAAlterEnergy: public ActivatedAbilityTP
|
||||
{
|
||||
public:
|
||||
int energy;
|
||||
|
||||
AAAlterEnergy(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable * _target, int energy, ManaCost * _cost = NULL,
|
||||
int who = TargetChooser::UNSET);
|
||||
int resolve();
|
||||
const string getMenuText();
|
||||
AAAlterEnergy * clone() const;
|
||||
~AAAlterEnergy();
|
||||
};
|
||||
/* Standard Damager, can choose a NEW target each time the price is paid */
|
||||
class TADamager: public TargetAbility
|
||||
{
|
||||
|
||||
@@ -216,6 +216,19 @@ public:
|
||||
virtual SnowCost * clone() const;
|
||||
};
|
||||
|
||||
//Energy cost
|
||||
class EnergyCost : public ExtraCost
|
||||
{
|
||||
private:
|
||||
int enc;
|
||||
|
||||
public:
|
||||
EnergyCost(int enc = 0);
|
||||
virtual int canPay();
|
||||
virtual int doPay();
|
||||
virtual EnergyCost * clone() const;
|
||||
};
|
||||
|
||||
//untap cost
|
||||
class UnTapCost : public ExtraCost
|
||||
{
|
||||
@@ -295,6 +308,16 @@ public:
|
||||
virtual int doPay();
|
||||
virtual Delve * clone() const;
|
||||
};
|
||||
//improvise
|
||||
class Improvise : public ExtraCost
|
||||
{
|
||||
public:
|
||||
Improvise(TargetChooser *_tc = NULL);
|
||||
virtual int canPay();
|
||||
virtual int isPaymentSet();
|
||||
virtual int doPay();
|
||||
virtual Improvise * clone() const;
|
||||
};
|
||||
//offering cost
|
||||
class Offering : public ExtraCost
|
||||
{
|
||||
|
||||
@@ -262,7 +262,9 @@ class Constants
|
||||
CONDUITED = 140,
|
||||
CANBLOCKTAPPED = 141,
|
||||
OPPNOMAXHAND = 142,
|
||||
NB_BASIC_ABILITIES = 143,
|
||||
CANTCREW = 143,
|
||||
HIDDENFACE = 144,
|
||||
NB_BASIC_ABILITIES = 145,
|
||||
|
||||
RARITY_S = 'S', //Special Rarity
|
||||
RARITY_M = 'M', //Mythics
|
||||
|
||||
@@ -42,6 +42,7 @@ public:
|
||||
int skippingTurn;
|
||||
int extraTurn;
|
||||
int drawCounter;
|
||||
int energyCount;
|
||||
int epic;
|
||||
int forcefield;
|
||||
int initLife;
|
||||
|
||||
@@ -595,6 +595,13 @@ int OrderedAIAction::getEfficiency()
|
||||
efficiency = 90;
|
||||
}
|
||||
}
|
||||
else if (dynamic_cast<AAAlterEnergy *>(a))
|
||||
{
|
||||
if (playerAbilityTarget && playerAbilityTarget == p)
|
||||
{
|
||||
efficiency = 90;
|
||||
}
|
||||
}
|
||||
else if (ATokenCreator * atc = dynamic_cast<ATokenCreator *>(a))
|
||||
{
|
||||
efficiency = 80;
|
||||
|
||||
@@ -1010,6 +1010,40 @@ AAAlterPoison::~AAAlterPoison()
|
||||
{
|
||||
}
|
||||
|
||||
//AA Energy Counters
|
||||
AAAlterEnergy::AAAlterEnergy(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable * _target, int energy, ManaCost * _cost,
|
||||
int who) :
|
||||
ActivatedAbilityTP(observer, _id, _source, _target, _cost, who), energy(energy)
|
||||
{
|
||||
}
|
||||
|
||||
int AAAlterEnergy::resolve()
|
||||
{
|
||||
Damageable * _target = (Damageable *) getTarget();
|
||||
if (_target)
|
||||
{
|
||||
Player * pTarget = (Player*)_target;
|
||||
if(pTarget)
|
||||
pTarget->energyCount += energy;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const string AAAlterEnergy::getMenuText()
|
||||
{
|
||||
WParsedInt parsedNum(energy);
|
||||
return _(parsedNum.getStringValue() + " Energy ").c_str();
|
||||
}
|
||||
|
||||
AAAlterEnergy * AAAlterEnergy::clone() const
|
||||
{
|
||||
return NEW AAAlterEnergy(*this);
|
||||
}
|
||||
|
||||
AAAlterEnergy::~AAAlterEnergy()
|
||||
{
|
||||
}
|
||||
|
||||
//Damage Prevent
|
||||
AADamagePrevent::AADamagePrevent(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable * _target, int preventing, ManaCost * _cost,
|
||||
int who) :
|
||||
@@ -2011,6 +2045,12 @@ int AAProliferate::resolve()
|
||||
a->oneShot = true;
|
||||
pcounters.push_back(a);
|
||||
}
|
||||
else if(pTarget && pTarget->energyCount && pTarget == source->controller())
|
||||
{
|
||||
MTGAbility * a = NEW AAAlterEnergy(game, game->mLayers->actionLayer()->getMaxId(), source, target, 1, NULL);
|
||||
a->oneShot = true;
|
||||
pcounters.push_back(a);
|
||||
}
|
||||
else if (cTarget && cTarget->counters)
|
||||
{
|
||||
Counters * counters = cTarget->counters;
|
||||
@@ -7909,17 +7949,9 @@ int AACastCard::resolveSpell()
|
||||
}
|
||||
if (_target)
|
||||
{
|
||||
|
||||
if (_target->isLand())
|
||||
{
|
||||
MTGCardInstance * copy = _target->controller()->game->putInZone(_target, _target->currentZone, source->controller()->game->temp,noEvent);
|
||||
copy->changeController(source->controller(),true);
|
||||
Spell * spell = NEW Spell(game, 0,copy,NULL,NULL, 1);
|
||||
spell->resolve();
|
||||
delete spell;
|
||||
}
|
||||
else
|
||||
{
|
||||
putinplay = true;
|
||||
|
||||
Spell * spell = NULL;
|
||||
MTGCardInstance * copy = NULL;
|
||||
if ((normal || asNormalMadness)||(!_target->hasType(Subtypes::TYPE_INSTANT) && !_target->hasType(Subtypes::TYPE_SORCERY)))
|
||||
@@ -7943,12 +7975,24 @@ int AACastCard::resolveSpell()
|
||||
if (game->targetChooser)
|
||||
{
|
||||
game->targetChooser->Owner = source->controller();
|
||||
spell = game->mLayers->stackLayer()->addSpell(copy, game->targetChooser, NULL, 1, 0);
|
||||
if(putinplay)
|
||||
{
|
||||
spell = NEW Spell(game, 0,copy,game->targetChooser,NULL, 1);
|
||||
spell->resolve();
|
||||
}
|
||||
else
|
||||
spell = game->mLayers->stackLayer()->addSpell(copy, game->targetChooser, NULL, 1, 0);
|
||||
game->targetChooser = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
spell = game->mLayers->stackLayer()->addSpell(copy, NULL, NULL, 1, 0);
|
||||
if(putinplay)
|
||||
{
|
||||
spell = NEW Spell(game, 0,copy,NULL,NULL, 1);
|
||||
spell->resolve();
|
||||
}
|
||||
else
|
||||
spell = game->mLayers->stackLayer()->addSpell(copy, NULL, NULL, 1, 0);
|
||||
}
|
||||
|
||||
if (copy->has(Constants::STORM))
|
||||
@@ -7980,7 +8024,7 @@ int AACastCard::resolveSpell()
|
||||
andAbilityClone->addToGame();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this->forceDestroy = true;
|
||||
processed = true;
|
||||
return 1;
|
||||
|
||||
@@ -533,6 +533,7 @@ void CardGui::AlternateRender(MTGCard * card, const Pos& pos)
|
||||
// Draw the "unknown" card model
|
||||
JRenderer * renderer = JRenderer::GetInstance();
|
||||
JQuadPtr q;
|
||||
MTGCardInstance * thiscard = dynamic_cast<MTGCardInstance*> (card);
|
||||
|
||||
float x = pos.actX;
|
||||
|
||||
@@ -553,6 +554,14 @@ void CardGui::AlternateRender(MTGCard * card, const Pos& pos)
|
||||
items.clear();
|
||||
if (q.get() && q->mTex)
|
||||
{
|
||||
//test
|
||||
//draw black border ingame only
|
||||
if(thiscard && thiscard->getObserver())
|
||||
{
|
||||
renderer->FillRoundRect((pos.actX - (pos.actZ * 84.f))-11.5f,(pos.actY - (pos.actZ * 119.7f))-14.f,pos.actZ * 168.f + 6.5f,pos.actZ * 239.4f + 12.f,8.f,ARGB(255,5,5,5));
|
||||
renderer->DrawRoundRect((pos.actX - (pos.actZ * 84.f))-11.5f,(pos.actY - (pos.actZ * 119.7f))-14.f,pos.actZ * 168.f + 6.5f,pos.actZ * 239.4f + 12.f,8.f,ARGB(50,240,240,240));
|
||||
}
|
||||
|
||||
q->SetHotSpot(static_cast<float> (q->mTex->mWidth / 2), static_cast<float> (q->mTex->mHeight / 2));
|
||||
|
||||
float scale = pos.actZ * 250 / q->mHeight;
|
||||
|
||||
@@ -232,6 +232,37 @@ int SnowCost::doPay()
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Energy Cost
|
||||
EnergyCost * EnergyCost::clone() const
|
||||
{
|
||||
EnergyCost * ec = NEW EnergyCost(*this);
|
||||
return ec;
|
||||
}
|
||||
|
||||
EnergyCost::EnergyCost(int enc) :
|
||||
ExtraCost("Energy Cost"),enc(enc)
|
||||
{
|
||||
}
|
||||
|
||||
int EnergyCost::canPay()
|
||||
{
|
||||
if(source->controller()->energyCount >= enc)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EnergyCost::doPay()
|
||||
{
|
||||
if(source->controller()->energyCount)
|
||||
{
|
||||
source->controller()->energyCount -= enc;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//life cost
|
||||
LifeCost * LifeCost::clone() const
|
||||
{
|
||||
@@ -1118,6 +1149,74 @@ int Delve::doPay()
|
||||
return 0;
|
||||
}
|
||||
|
||||
//IMPROVISE
|
||||
Improvise * Improvise::clone() const
|
||||
{
|
||||
Improvise * ec = NEW Improvise(*this);
|
||||
if (tc)
|
||||
ec->tc = tc->clone();
|
||||
return ec;
|
||||
}
|
||||
|
||||
Improvise::Improvise(TargetChooser *_tc) :
|
||||
ExtraCost("Select Artifacts To Tap", _tc)
|
||||
{
|
||||
}
|
||||
|
||||
int Improvise::canPay()
|
||||
{
|
||||
return isPaymentSet();
|
||||
}
|
||||
|
||||
int Improvise::isPaymentSet()
|
||||
{
|
||||
ManaCost * toReduce = NEW ManaCost(source->getManaCost());
|
||||
tc->maxtargets = source->getManaCost()->getCost(Constants::MTG_COLOR_ARTIFACT);
|
||||
if (tc->getNbTargets())
|
||||
{
|
||||
toReduce->remove(Constants::MTG_COLOR_ARTIFACT, tc->getNbTargets());
|
||||
}
|
||||
if (target && (!source->controller()->getManaPool()->canAfford(toReduce)))
|
||||
{
|
||||
target = NULL;
|
||||
SAFE_DELETE(toReduce);
|
||||
return 0;
|
||||
}
|
||||
if (target && (source->controller()->getManaPool()->canAfford(toReduce)))
|
||||
{
|
||||
/*if (target->getObserver()->guiOpenDisplay)
|
||||
target->getObserver()->ButtonPressed(target->getObserver()->guiOpenDisplay);*/
|
||||
SAFE_DELETE(toReduce);
|
||||
return 1;
|
||||
}
|
||||
SAFE_DELETE(toReduce);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Improvise::doPay()
|
||||
{
|
||||
if (target && tc->getNbTargets())
|
||||
{
|
||||
ManaCost * toReduce = NEW ManaCost(source->getManaCost());
|
||||
|
||||
toReduce->remove(Constants::MTG_COLOR_ARTIFACT, tc->getNbTargets());
|
||||
|
||||
target->controller()->getManaPool()->pay(toReduce);
|
||||
SAFE_DELETE(toReduce);
|
||||
vector<Targetable*>targetlist = tc->getTargetsFrom();
|
||||
for (vector<Targetable*>::iterator it = targetlist.begin(); it != targetlist.end(); it++)
|
||||
{
|
||||
MTGCardInstance * targetCard = dynamic_cast<MTGCardInstance*>(*it);
|
||||
source->storedCard = targetCard->createSnapShot();
|
||||
targetCard->tap();
|
||||
}
|
||||
if (tc)
|
||||
tc->initTargets();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////
|
||||
//Sacrifice target as cost for Offering
|
||||
Offering * Offering::clone() const
|
||||
|
||||
@@ -31,6 +31,7 @@ void GuiAvatar::Render()
|
||||
JRenderer * r = JRenderer::GetInstance();
|
||||
int life = player->life;
|
||||
int poisonCount = player->poisonCount;
|
||||
int energyCount = player->energyCount;
|
||||
WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT);
|
||||
mFont->SetScale(DEFAULT_MAIN_FONT_SCALE);
|
||||
//Avatar
|
||||
@@ -108,10 +109,10 @@ void GuiAvatar::Render()
|
||||
{
|
||||
case TOP_LEFT:
|
||||
mFont->SetColor(ARGB((int)actA / 4, 0, 0, 0));
|
||||
mFont->DrawString(buffer, actX + 2, actY + 2);
|
||||
mFont->DrawString(buffer, actX + 2, actY - 2);
|
||||
mFont->SetScale(1.3f);
|
||||
mFont->SetColor(ARGB((int)actA, lx, ly, lz));
|
||||
mFont->DrawString(buffer, actX + 1, actY + 1);
|
||||
mFont->DrawString(buffer, actX + 1, actY - 1);
|
||||
mFont->SetScale(1);
|
||||
break;
|
||||
case BOTTOM_RIGHT:
|
||||
@@ -122,8 +123,8 @@ void GuiAvatar::Render()
|
||||
break;
|
||||
}
|
||||
//poison
|
||||
char poison[5];
|
||||
if (poisonCount > 0)
|
||||
char poison[10];
|
||||
if (poisonCount >= 0)
|
||||
{
|
||||
sprintf(poison, "%i", poisonCount);
|
||||
switch (corner)
|
||||
@@ -138,6 +139,23 @@ void GuiAvatar::Render()
|
||||
break;
|
||||
}
|
||||
}
|
||||
//energy
|
||||
char energy[15];
|
||||
if (energyCount >= 0)
|
||||
{
|
||||
sprintf(energy, "%i", energyCount);
|
||||
switch (corner)
|
||||
{
|
||||
case TOP_LEFT:
|
||||
mFont->SetColor(ARGB((int)actA / 1, 255, 255, 0));
|
||||
mFont->DrawString(energy, actX + 2, actY + 17);
|
||||
break;
|
||||
case BOTTOM_RIGHT:
|
||||
mFont->SetColor(ARGB((int)actA / 1 ,255, 255, 0));
|
||||
mFont->DrawString(energy, actX, actY - 27, JGETEXT_RIGHT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
PlayGuiObject::Render();
|
||||
}
|
||||
|
||||
|
||||
@@ -329,6 +329,37 @@ int AbilityFactory::parseCastRestrictions(MTGCardInstance * card, Player * playe
|
||||
if(!count)
|
||||
return 0;
|
||||
}
|
||||
check = restriction[i].find("revolt");
|
||||
if(check != string::npos)
|
||||
{
|
||||
int count = 0;
|
||||
for(unsigned int k = 0; k < player->game->hand->cardsSeenThisTurn.size(); k++)
|
||||
{
|
||||
MTGCardInstance * tCard = player->game->hand->cardsSeenThisTurn[k];
|
||||
if(tCard && tCard->previousZone == card->controller()->game->battlefield)
|
||||
count++;
|
||||
}
|
||||
for(unsigned int k = 0; k < player->game->exile->cardsSeenThisTurn.size(); k++)
|
||||
{
|
||||
MTGCardInstance * tCard = player->game->exile->cardsSeenThisTurn[k];
|
||||
if(tCard && tCard->previousZone == card->controller()->game->battlefield)
|
||||
count++;
|
||||
}
|
||||
for(unsigned int k = 0; k < player->game->library->cardsSeenThisTurn.size(); k++)
|
||||
{
|
||||
MTGCardInstance * tCard = player->game->library->cardsSeenThisTurn[k];
|
||||
if(tCard && tCard->previousZone == card->controller()->game->battlefield)
|
||||
count++;
|
||||
}
|
||||
for(unsigned int k = 0; k < player->game->graveyard->cardsSeenThisTurn.size(); k++)
|
||||
{
|
||||
MTGCardInstance * tCard = player->game->graveyard->cardsSeenThisTurn[k];
|
||||
if(tCard && tCard->previousZone == card->controller()->game->battlefield)
|
||||
count++;
|
||||
}
|
||||
if(!count)
|
||||
return 0;
|
||||
}
|
||||
check = restriction[i].find("morbid");
|
||||
if(check != string::npos)
|
||||
{
|
||||
@@ -2949,6 +2980,17 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
||||
return a;
|
||||
}
|
||||
|
||||
//alter energy
|
||||
vector<string> splitEnergy = parseBetween(s, "alterenergy:", " ", false);
|
||||
if (splitEnergy.size())
|
||||
{
|
||||
int energy = atoi(splitEnergy[1].c_str());
|
||||
Targetable * t = spell ? spell->getNextTarget() : NULL;
|
||||
MTGAbility * a = NEW AAAlterEnergy(observer, id, card, t, energy, NULL, who);
|
||||
a->oneShot = 1;
|
||||
return a;
|
||||
}
|
||||
|
||||
//prevent next damage
|
||||
vector<string> splitPrevent = parseBetween(s, "prevent:", " ", false);
|
||||
if (splitPrevent.size())
|
||||
|
||||
@@ -173,7 +173,9 @@ const char* Constants::MTGBasicAbilities[] = {
|
||||
"asflash",
|
||||
"conduited",
|
||||
"canblocktapped",
|
||||
"oppnomaxhand"
|
||||
"oppnomaxhand",
|
||||
"cantcrew",
|
||||
"hiddenface"//test for facedown
|
||||
};
|
||||
|
||||
map<string,int> Constants::MTGBasicAbilitiesMap;
|
||||
|
||||
@@ -159,6 +159,15 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan
|
||||
tc = tcf.createTargetChooser("creature|mybattlefield", c);
|
||||
manaCost->addExtraCost(NEW Offering(tc,true));
|
||||
}
|
||||
else if(value.substr(0,2) == "e:")
|
||||
{//Energy Cost
|
||||
vector<string>valSplit = parseBetween(value,"e:"," ",false);
|
||||
if (valSplit.size()) {
|
||||
WParsedInt* energytopay = NEW WParsedInt(valSplit[1], NULL, c);
|
||||
manaCost->addExtraCost(NEW EnergyCost(energytopay->getValue()));
|
||||
SAFE_DELETE(energytopay);
|
||||
}
|
||||
}
|
||||
else
|
||||
//Exile
|
||||
manaCost->addExtraCost(NEW ExileTargetCost(tc));
|
||||
@@ -248,12 +257,19 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan
|
||||
break;
|
||||
}
|
||||
case 'i' :
|
||||
if(value == "improvise")
|
||||
{
|
||||
if(!tc)
|
||||
tc = tcf.createTargetChooser("artifact[-tapped]|myBattlefield", c);
|
||||
manaCost->addExtraCost(NEW Improvise(tc));
|
||||
}
|
||||
else
|
||||
{
|
||||
SAFE_DELETE(tc);
|
||||
manaCost->add(0,1);
|
||||
manaCost->addExtraCost(NEW SnowCost);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'q':
|
||||
if(value == "q")
|
||||
{
|
||||
|
||||
@@ -34,6 +34,7 @@ Player::Player(GameObserver *observer, string file, string fileSmall, MTGDeck *
|
||||
skippingTurn = 0;
|
||||
extraTurn = 0;
|
||||
drawCounter = 0;
|
||||
energyCount = 0;
|
||||
epic = 0;
|
||||
forcefield = 0;
|
||||
raidcount = 0;
|
||||
|
||||
@@ -409,6 +409,7 @@ void Rules::initGame(GameObserver *g, bool currentPlayerSet)
|
||||
p->poisonCount = initState.playerData[i].player->poisonCount;
|
||||
p->damageCount = initState.playerData[i].player->damageCount;
|
||||
p->preventable = initState.playerData[i].player->preventable;
|
||||
p->energyCount = initState.playerData[i].player->energyCount;
|
||||
if (initState.playerData[i].player->mAvatarName.size())
|
||||
{
|
||||
p->mAvatarName = initState.playerData[i].player->mAvatarName;
|
||||
|
||||
Reference in New Issue
Block a user