Erwan
- new features by Zethfox: -- "oneshot" optional parameters for lords (helps fixing issues with bouncelands) -- Life as a cost (avoids using a dirty trick of paying life as an effect) -- set life total abilitiy (lifeset -- new auto lines: autostack, autoexile The test suite passes with these changes, also no test using these abilities has been added yet
This commit is contained in:
@@ -51,6 +51,10 @@ public:
|
||||
intValue = computeX(spell,card);
|
||||
}else if (s == "manacost"){
|
||||
intValue = target->getManaCost()->getConvertedCost();
|
||||
}else if (s == "lifetotal"){
|
||||
intValue = target->controller()->life;
|
||||
}else if (s == "opponentlifetotal"){
|
||||
intValue = target->controller()->opponent()->life;
|
||||
}else if (s == "p"){
|
||||
intValue = target->power;
|
||||
}else if (s == "t"){
|
||||
@@ -699,7 +703,7 @@ class AALifer:public ActivatedAbilityTP{
|
||||
if (_target->type_as_damageable == DAMAGEABLE_MTGCARDINSTANCE){
|
||||
_target = ((MTGCardInstance *)_target)->controller();
|
||||
}
|
||||
_target->life+=life->getValue();
|
||||
_target->life +=life->getValue();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -1166,7 +1170,6 @@ public:
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*Gives life each time a spell matching CardDescriptor's criteria are match . Optionnal manacost*/
|
||||
class ASpellCastLife:public MTGAbility{
|
||||
public:
|
||||
@@ -2087,7 +2090,43 @@ class AThisForEach:public MTGAbility, public NestedAbility{
|
||||
return a;
|
||||
}
|
||||
};
|
||||
//lifeset
|
||||
class AALifeSet:public ActivatedAbilityTP{
|
||||
public:
|
||||
WParsedInt * life;
|
||||
AALifeSet(int _id, MTGCardInstance * _source, Targetable * _target, WParsedInt * life, ManaCost * _cost=NULL, int doTap = 0, int who = TargetChooser::UNSET):ActivatedAbilityTP(_id,_source,_target,_cost,doTap,who),life(life){
|
||||
}
|
||||
|
||||
int resolve(){
|
||||
Damageable * _target = (Damageable *) getTarget();
|
||||
if(_target){
|
||||
if (_target->type_as_damageable == DAMAGEABLE_MTGCARDINSTANCE){
|
||||
_target = ((MTGCardInstance *)_target)->controller();
|
||||
}
|
||||
_target->life =life->getValue();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char * getMenuText(){
|
||||
return "Set Life";
|
||||
}
|
||||
|
||||
AALifeSet * clone() const{
|
||||
AALifeSet * a = NEW AALifeSet(*this);
|
||||
a->life = NEW WParsedInt(*(a->life));
|
||||
a->isClone = 1;
|
||||
return a;
|
||||
}
|
||||
|
||||
~AALifeSet(){
|
||||
SAFE_DELETE(life);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
//lifesetend
|
||||
class AADamager:public ActivatedAbilityTP{
|
||||
public:
|
||||
WParsedInt * damage;
|
||||
|
||||
@@ -55,6 +55,20 @@ public:
|
||||
virtual SacrificeCost * clone() const;
|
||||
};
|
||||
|
||||
//life cost
|
||||
class LifeCost: public ExtraCost{
|
||||
public:
|
||||
MTGCardInstance * target;
|
||||
LifeCost(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 LifeCost * clone() const;
|
||||
};
|
||||
|
||||
//tap other cost
|
||||
class TapTargetCost: public ExtraCost{
|
||||
public:
|
||||
|
||||
@@ -20,6 +20,64 @@ int ExtraCost::setSource(MTGCardInstance * _source){
|
||||
if (tc){ tc->source = _source; tc->targetter = _source;}
|
||||
return 1;
|
||||
}
|
||||
//life cost
|
||||
LifeCost * LifeCost::clone() const{
|
||||
LifeCost * ec = NEW LifeCost(*this);
|
||||
if (tc) ec->tc = tc->clone();
|
||||
return ec;
|
||||
}
|
||||
LifeCost::LifeCost(TargetChooser *_tc):ExtraCost(_tc){
|
||||
if (tc) tc->targetter = NULL;
|
||||
target = NULL;
|
||||
}
|
||||
|
||||
int LifeCost::setSource(MTGCardInstance * card){
|
||||
ExtraCost::setSource(card);
|
||||
if (tc) tc->targetter = NULL;
|
||||
if (!tc) target = card;
|
||||
return 1;
|
||||
}
|
||||
int LifeCost::setPayment(MTGCardInstance * card){
|
||||
if (tc) {
|
||||
int result = tc->addTarget(card);
|
||||
if (result) {
|
||||
target = card;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int LifeCost::isPaymentSet(){
|
||||
if (target) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LifeCost::canPay(){
|
||||
return 1;
|
||||
}
|
||||
int LifeCost::doPay(){
|
||||
MTGCardInstance * _target = (MTGCardInstance *) target;
|
||||
if(target){
|
||||
_target->controller()->life -= 1;
|
||||
target = NULL;
|
||||
if (tc) tc->initTargets();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void LifeCost::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", _("Life").c_str());
|
||||
mFont->DrawString(buffer, 20 ,20, JGETEXT_LEFT);
|
||||
}
|
||||
//endlifecost
|
||||
|
||||
//Tap target cost
|
||||
TapTargetCost * TapTargetCost::clone() const{
|
||||
TapTargetCost * ec = NEW TapTargetCost(*this);
|
||||
|
||||
@@ -354,6 +354,17 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
||||
else a1 = NEW GenericActivatedAbility(id, card, a1,NULL);
|
||||
return NEW MayAbility(id,a1,card);
|
||||
}
|
||||
//When...comes into play, choose one...
|
||||
found = s.find("choice ");
|
||||
if (found == 0){
|
||||
string s1 = sWithoutTc.substr(found+4);
|
||||
MTGAbility * a1 = parseMagicLine(s1,id,spell, card);
|
||||
if (!a1) return NULL;
|
||||
|
||||
if (tc) a1 = NEW GenericTargetAbility(id, card, tc, a1);
|
||||
else a1 = NEW GenericActivatedAbility(id, card, a1,NULL);
|
||||
return NEW MayAbility(id,a1,card,true);
|
||||
}
|
||||
|
||||
|
||||
//Multiple abilities for ONE cost
|
||||
@@ -498,10 +509,16 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
||||
|
||||
int mini = 0;
|
||||
int maxi = 0;
|
||||
|
||||
found = s.find(" >");
|
||||
if (found !=string::npos) mini = atoi(s.substr(found+2,1).c_str());
|
||||
|
||||
found = s.find(" <");
|
||||
if (found !=string::npos) maxi = atoi(s.substr(found+2,1).c_str());
|
||||
|
||||
found = s.find(" oneshot");
|
||||
if (found !=string::npos) oneShot = 1;
|
||||
|
||||
switch(i){
|
||||
case 0: result = NEW ALord(id, card, lordTargets, lordIncludeSelf, a); break;
|
||||
case 1: result = NEW AForeach(id, card, _target,lordTargets, lordIncludeSelf, a,mini,maxi); break;
|
||||
@@ -742,6 +759,25 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
||||
return a;
|
||||
}
|
||||
|
||||
//set life total
|
||||
found = s.find("lifeset");
|
||||
if (found != string::npos){
|
||||
size_t start = s.find(":",found);
|
||||
if (start == string::npos) start = s.find(" ",found);
|
||||
size_t end = s.find(" ",start);
|
||||
string d;
|
||||
if (end != string::npos){
|
||||
d = s.substr(start+1,end-start-1);
|
||||
}else{
|
||||
d = s.substr(start+1);
|
||||
}
|
||||
WParsedInt * life = NEW WParsedInt(d,spell,card);
|
||||
Damageable * t = NULL;
|
||||
if (spell) t = spell->getNextDamageableTarget();
|
||||
MTGAbility * a = NEW AALifeSet(id,card,t, life, NULL, 0, who);
|
||||
a->oneShot = 1;
|
||||
return a;
|
||||
}
|
||||
|
||||
//gain/lose life
|
||||
found = s.find("life:");
|
||||
@@ -1110,6 +1146,14 @@ int AbilityFactory::getAbilities(vector<MTGAbility *> * v, Spell * spell, MTGCar
|
||||
if (dest == zones->graveyard){
|
||||
magicText = card->magicTexts["graveyard"];
|
||||
break;
|
||||
}
|
||||
if (dest == zones->stack){
|
||||
magicText = card->magicTexts["stack"];
|
||||
break;
|
||||
}
|
||||
if (dest == zones->exile){
|
||||
magicText = card->magicTexts["exile"];
|
||||
break;
|
||||
}
|
||||
//Other zones needed ?
|
||||
return 0;
|
||||
|
||||
@@ -79,6 +79,23 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan
|
||||
}
|
||||
manaCost->addExtraCost(NEW TapTargetCost(tc));
|
||||
//tapcost
|
||||
|
||||
|
||||
//life cost
|
||||
}else if (value[0] == 'l'){
|
||||
//tap
|
||||
OutputDebugString("Life\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 LifeCost(tc));
|
||||
//end life cost
|
||||
|
||||
}else if (value[0] == 'c'){
|
||||
//Counters
|
||||
OutputDebugString("Counter\n");
|
||||
|
||||
Reference in New Issue
Block a user