Fixed primitives, updated italian lang file, added a new setting to sort decks by creation date (by default they will be sorted by name), added new filters to match cards that don't contain a particular color or that are multicolored, fixed an issue when the transformation with uynt is triggered by instant/sorcery or by card that left the battlefield before the ability ending turn, fixed a rendering overlap on mana symbols in deck editor, fixed some crashes on ManaCost parser (e.g. Filter by mana producer).

This commit is contained in:
Vittorio Alfieri
2021-11-15 21:38:04 +01:00
parent 2eed51dea6
commit 477ffa6a0c
16 changed files with 204 additions and 60 deletions

View File

@@ -873,8 +873,10 @@ Mute=Muto
Misc=Altri
Card Display Options=Opzioni di visualizzazione delle carte
All Black Borders=Tutti i bordi neri
Show Borders=Mostra i bordi
Sort decks by date=Ordina i mazzi per data
Show Tokens in Editor=Mostra i token nell'editor
Warning!!=Avvertimento!!
Warning!!!=Avvertimento!!!
Show Large Images in Grid Deck View=Mostra immagini grandi nella vista a griglia
Enable Prefetching=Abilita la pre-elaborazione
@@ -953,7 +955,7 @@ Offer Choice=Offri la scelta
Always Pay=Paga sempre
#Comandi:
Key Bindings=Associazione dei comandi
Key Bindings=Comandi
Load Defaults...=Caricare impostazioni di default...
Press a key to associate.=Premere un tasto per associare.
New binding...=Nuova associazione...
@@ -996,6 +998,8 @@ Interrupt my abilities=Interrompi le mie abilita'
Interrupt my spells=Interrompi i miei incantesimi
Interrupt opponent's end of turn=Interrompi la fine del turno dell'avversario
Credits=Ringraziamenti
###########
# TROFEOS #
###########

View File

@@ -3786,9 +3786,8 @@ name=Athreos, Shroud-Veiled
abilities=indestructible
auto=this(variable{orzhov}<7) transforms((removetypes,newability[becomes(Legendary Enchantment God)]))
auto=this(variable{orzhov}>6) transforms((Legendary Enchantment Creature))
auto=@each my endofturn:counter(0/0,1,Coin) target(other creature)
auto=@movedto(creature[counter{0/0,1,Coin}]|Graveyard):all(trigger[to]) moveTo(ownerBattlefield) oneshot
auto=@movedto(creature[counter{0/0,1,Coin}]|Exile):all(trigger[to]) moveTo(myBattlefield) oneshot
auto=@each my endofturn:counter(0/0,1,Coin) target(other creature|battlefield)
auto=@movedto(creature[counter{0/0.1.Coin}]|graveyard,exile):name(Return on battlefield) all(trigger[to]) name(Return on battlefield) moveTo(mybattlefield)
text=Indestructible -- As long as your devotion to white and black is less than seven, Athreos isn't a creature. -- At the beginning of your end step, put a coin counter on another target creature. -- Whenever a creature with a coin counter on it dies or is put into exile, return that card to the battlefield under your control.
mana={4}{W}{B}
type=Legendary Enchantment Creature
@@ -28843,7 +28842,7 @@ toughness=2
[card]
name=Gilded Light
abilities=cycling
auto=playershroud ueot
auto=all(*|myBattlefield) transforms((,newability[playershroud])) ueot
autohand=__CYCLING__({2})
text=You gain shroud until end of turn. (You can't be the target of spells or abilities.) -- Cycling {2} ({2}, Discard this card: Draw a card.)
mana={1}{W}
@@ -31574,7 +31573,7 @@ abilities=trample
auto=choice counter(1/1)
auto=choice aslongas(creature|myBattlefield) haste
auto=this(variable{controllerturn}) opponentshroud
auto=this(variable{controllerturn}) playershroud
auto=this(variable{controllerturn}) controllershroud
text=Riot (This creature enters the battlefield with your choice of a +1/+1 counter or haste.) -- Trample -- As long as it's your turn, you and Gruul Spellbreaker have hexproof.
mana={1}{R}{G}
type=Creature
@@ -31622,8 +31621,7 @@ toughness=2
[card]
name=Guardian Archon
abilities=flying
auto=name(Choose opponent) target(opponent) donothing
auto=this(cantargetcard(*[-effectactivated]) {0}:name(Gain protection) all(this) becomes(effectactivated) forever && target(*|mybattlefield) transforms((,newability[opponentshroud],newability[playershroud])) ueot
auto=this(cantargetcard(*[-effectactivated]) {0}:name(Gain protection) all(this) becomes(effectactivated) forever && target(*|mybattlefield) transforms((,newability[opponentshroud],newability[controllershroud])) ueot
text=Flying -- As Guardian Archon enters the battlefield, secretly choose an opponent. -- Reveal the player you chose: You and target permanent you control each gain protection from the chosen player until end of turn. Activate only once.
mana={4}{W}{W}
type=Creature
@@ -39039,7 +39037,7 @@ toughness=1
[/card]
[card]
name=Keen-Eared Sentry
abilities=playershroud
abilities=controllershroud
auto=@counteradded(0/0,1,Explore) from(*[dungeon]|opponentcommandzone):transforms((,newability[nodngopp])) ueot
text=You have hexproof. (You can't be the target of spells or abilities your opponents control.) -- Your opponents can't venture into the dungeon more than once each turn.
mana={1}{W}
@@ -40384,6 +40382,7 @@ toughness=4
[/card]
[card]
name=Krav, the Unredeemed
abilities=partner
auto=may name(Put partner on your hand) moveto(myhand) target(Regna^ the Redeemer|mylibrary)
auto={B}{S(creature|myBattlefield)}:name(Sacrifice 1 creature and target yourself) name(Sacrifice 1 creature and target yourself) all(this) counter(1/1,1) && life:1 controller && draw:1 controller
auto={B}{S(creature|myBattlefield)}:name(Sacrifice 1 creature and target opponent) name(Sacrifice 1 creature and target opponent) all(this) counter(1/1,1) && life:1 opponent && draw:1 opponent
@@ -41335,8 +41334,7 @@ toughness=3
[card]
name=Lazotep Plating
auto=_AMASS_(1)
auto=playershroud ueot
auto=all(creature|myBattlefield) opponentshroud
auto=all(*|myBattlefield) transforms((,newability[opponentshroud],newability[controllershroud])) ueot
text=Amass 1. (Put a +1/+1 counter on an Army you control. If you don't control one, create a 0/0 black Zombie Army creature token first.) -- You and permanents you control gain hexproof until end of turn. (You and they can't be the targets of spells or abilities your opponents control.)
mana={1}{U}
type=Instant
@@ -50594,8 +50592,8 @@ type=Artifact
[/card]
[card]
name=Orbs of Warding
abilities=playershroud
auto=@damaged(controller) from(creature|battlefield):life:1
abilities=controllershroud
auto=@damageof(player) from(creature|battlefield):name(Prevent 1 damage) life:1 controller
text=You have hexproof. (You can't be the target of spells or abilities your opponents control.) -- If a creature would deal damage to you, prevent 1 of that damage.
mana={5}
type=Artifact
@@ -54951,11 +54949,11 @@ auto={2}{T}{counter(0/0,1,brick)}:add{B}
auto={2}{T}{counter(0/0,1,brick)}:add{W}
auto={2}{T}{counter(0/0,1,brick)}:add{R}
auto={2}{T}{counter(0/0,1,brick)}:add{U}
auto={T}{restriction type(this[counter(brick)>=3])~morethan~0}:add{G}{G}{G}
auto={T}{restriction type(this[counter(brick)>=3])~morethan~0}:add{B}{B}{B}
auto={T}{restriction type(this[counter(brick)>=3])~morethan~0}:add{W}{W}{W}
auto={T}{restriction type(this[counter(brick)>=3])~morethan~0}:add{R}{R}{R}
auto={T}{restriction type(this[counter(brick)>=3])~morethan~0}:add{U}{U}{U}
auto=this(counter{0/0.1.brick}>=3) {T}:add{G}{G}{G}
auto=this(counter{0/0.1.brick}>=3) {T}:add{B}{B}{B}
auto=this(counter{0/0.1.brick}>=3) {T}:add{W}{W}{W}
auto=this(counter{0/0.1.brick}>=3) {T}:add{R}{R}{R}
auto=this(counter{0/0.1.brick}>=3) {T}:add{U}{U}{U}
text={2}, {T}: Add one mana of any color to your mana pool. Put a brick counter on Pyramid of the Pantheon. -- {T}: Add three mana of any one color to your mana pool. Activate this ability only if there are three or more brick counters on Pyramid of the Pantheon.
mana={1}
type=Artifact
@@ -83188,7 +83186,8 @@ toughness=3
[card]
name=Zara, Renegade Recruiter
abilities=flying
auto=_ATTACKING_reveal:type:*:opponenthand revealzone(opponenthand) optionone name(Reveal) target(creature|reveal) moveto(mybattlefield) and!( transforms((,newability[ninjutsu],newability[phaseaction[endofturn] moveto(ownerhand) all(this)])) forever )! optiononeend optiontwo all(*|reveal) moveto(opponenthand) optiontwoend revealend
aicode=activate target(creature|opponenthand) moveto(mybattlefield) and!( transforms((,newability[ninjutsu],newability[phaseaction[endofturn once sourceinplay] moveto(ownerhand)])) forever )!
auto=_ATTACKING_reveal:type:*:opponenthand revealzone(opponenthand) optionone name(Reveal) target(creature|reveal) moveto(mybattlefield) and!( transforms((,newability[ninjutsu],newability[phaseaction[endofturn] moveto(ownerhand)])) forever )! optiononeend optiontwo all(*|reveal) moveto(opponenthand) optiontwoend revealend
text=Flying -- Whenever Zara, Renegade Recruiter attacks, look at defending player's hand. You may put a creature card from it onto the battlefield under your control tapped and attacking that player or a planeswalker they control. Return that creature to its owner's hand at the beginning of the next end step.
mana={3}{U}{R}
type=Legendary Creature

View File

@@ -993,7 +993,7 @@ toughness=3
[/card]
[card]
name=Aegis of the Gods
abilities=playershroud
abilities=controllershroud
text=You have hexproof. (You can't be the target of spells or abilities your opponents control.)
mana={1}{W}
type=Enchantment Creature
@@ -82395,11 +82395,26 @@ type=Artifact
[card]
name=Oona, Queen of the Fae
abilities=flying
auto={X}{UB}:name(green) target(opponent) reveal:x revealzone(targetedpersonslibrary) optionone all(*|reveal) moveto(exile) and!( if cantargetcard(*[green]|*) then token(Faerie Rogue,Creature Faerie Rogue,1/1,flying,blue,black) )! optiononeend revealend
auto={X}{UB}:name(blue) target(opponent) reveal:x revealzone(targetedpersonslibrary) optionone all(*|reveal) moveto(exile) and!( if cantargetcard(*[blue]|*) then token(Faerie Rogue,Creature Faerie Rogue,1/1,flying,blue,black) )! optiononeend revealend
auto={X}{UB}:name(red) target(opponent) reveal:x revealzone(targetedpersonslibrary) optionone all(*|reveal) moveto(exile) and!( if cantargetcard(*[red]|*) then token(Faerie Rogue,Creature Faerie Rogue,1/1,flying,blue,black) )! optiononeend revealend
auto={X}{UB}:name(black) target(opponent) reveal:x revealzone(targetedpersonslibrary) optionone all(*|reveal) moveto(exile) and!( if cantargetcard(*[black]|*) then token(Faerie Rogue,Creature Faerie Rogue,1/1,flying,blue,black) )! optiononeend revealend
auto={X}{UB}:name(white) target(opponent) reveal:x revealzone(targetedpersonslibrary) optionone all(*|reveal) moveto(exile) and!( if cantargetcard(*[white]|*) then token(Faerie Rogue,Creature Faerie Rogue,1/1,flying,blue,black) )! optiononeend revealend
auto={1}{UB}:name(X=1) activatechooseacolor all(*[zpos<=1]|opponentLibrary) moveto(exile) and!( if cantargetcard(*[chosencolor]|*) then token(Faerie Rogue,Creature Faerie Rogue,1/1,flying,blue,black) )! activatechooseend
auto={2}{UB}:name(X=2) activatechooseacolor all(*[zpos<=2]|opponentLibrary) moveto(exile) and!( if cantargetcard(*[chosencolor]|*) then token(Faerie Rogue,Creature Faerie Rogue,1/1,flying,blue,black) )! activatechooseend
auto={3}{UB}:name(X=3) activatechooseacolor all(*[zpos<=3]|opponentLibrary) moveto(exile) and!( if cantargetcard(*[chosencolor]|*) then token(Faerie Rogue,Creature Faerie Rogue,1/1,flying,blue,black) )! activatechooseend
auto={4}{UB}:name(X=4) activatechooseacolor all(*[zpos<=4]|opponentLibrary) moveto(exile) and!( if cantargetcard(*[chosencolor]|*) then token(Faerie Rogue,Creature Faerie Rogue,1/1,flying,blue,black) )! activatechooseend
auto={5}{UB}:name(X=5) activatechooseacolor all(*[zpos<=5]|opponentLibrary) moveto(exile) and!( if cantargetcard(*[chosencolor]|*) then token(Faerie Rogue,Creature Faerie Rogue,1/1,flying,blue,black) )! activatechooseend
auto={6}{UB}:name(X=6) activatechooseacolor all(*[zpos<=6]|opponentLibrary) moveto(exile) and!( if cantargetcard(*[chosencolor]|*) then token(Faerie Rogue,Creature Faerie Rogue,1/1,flying,blue,black) )! activatechooseend
auto={7}{UB}:name(X=7) activatechooseacolor all(*[zpos<=7]|opponentLibrary) moveto(exile) and!( if cantargetcard(*[chosencolor]|*) then token(Faerie Rogue,Creature Faerie Rogue,1/1,flying,blue,black) )! activatechooseend
auto={8}{UB}:name(X=8) activatechooseacolor all(*[zpos<=8]|opponentLibrary) moveto(exile) and!( if cantargetcard(*[chosencolor]|*) then token(Faerie Rogue,Creature Faerie Rogue,1/1,flying,blue,black) )! activatechooseend
auto={9}{UB}:name(X=9) activatechooseacolor all(*[zpos<=9]|opponentLibrary) moveto(exile) and!( if cantargetcard(*[chosencolor]|*) then token(Faerie Rogue,Creature Faerie Rogue,1/1,flying,blue,black) )! activatechooseend
auto={10}{UB}:name(X=10) activatechooseacolor all(*[zpos<=10]|opponentLibrary) moveto(exile) and!( if cantargetcard(*[chosencolor]|*) then token(Faerie Rogue,Creature Faerie Rogue,1/1,flying,blue,black) )! activatechooseend
auto={11}{UB}:name(X=11) activatechooseacolor all(*[zpos<=11]|opponentLibrary) moveto(exile) and!( if cantargetcard(*[chosencolor]|*) then token(Faerie Rogue,Creature Faerie Rogue,1/1,flying,blue,black) )! activatechooseend
auto={12}{UB}:name(X=12) activatechooseacolor all(*[zpos<=12]|opponentLibrary) moveto(exile) and!( if cantargetcard(*[chosencolor]|*) then token(Faerie Rogue,Creature Faerie Rogue,1/1,flying,blue,black) )! activatechooseend
auto={13}{UB}:name(X=13) activatechooseacolor all(*[zpos<=13]|opponentLibrary) moveto(exile) and!( if cantargetcard(*[chosencolor]|*) then token(Faerie Rogue,Creature Faerie Rogue,1/1,flying,blue,black) )! activatechooseend
auto={14}{UB}:name(X=14) activatechooseacolor all(*[zpos<=14]|opponentLibrary) moveto(exile) and!( if cantargetcard(*[chosencolor]|*) then token(Faerie Rogue,Creature Faerie Rogue,1/1,flying,blue,black) )! activatechooseend
auto={15}{UB}:name(X=15) activatechooseacolor all(*[zpos<=15]|opponentLibrary) moveto(exile) and!( if cantargetcard(*[chosencolor]|*) then token(Faerie Rogue,Creature Faerie Rogue,1/1,flying,blue,black) )! activatechooseend
auto={16}{UB}:name(X=16) activatechooseacolor all(*[zpos<=16]|opponentLibrary) moveto(exile) and!( if cantargetcard(*[chosencolor]|*) then token(Faerie Rogue,Creature Faerie Rogue,1/1,flying,blue,black) )! activatechooseend
auto={17}{UB}:name(X=17) activatechooseacolor all(*[zpos<=7]|opponentLibrary) moveto(exile) and!( if cantargetcard(*[chosencolor]|*) then token(Faerie Rogue,Creature Faerie Rogue,1/1,flying,blue,black) )! activatechooseend
auto={18}{UB}:name(X=18) activatechooseacolor all(*[zpos<=18]|opponentLibrary) moveto(exile) and!( if cantargetcard(*[chosencolor]|*) then token(Faerie Rogue,Creature Faerie Rogue,1/1,flying,blue,black) )! activatechooseend
auto={19}{UB}:name(X=19) activatechooseacolor all(*[zpos<=19]|opponentLibrary) moveto(exile) and!( if cantargetcard(*[chosencolor]|*) then token(Faerie Rogue,Creature Faerie Rogue,1/1,flying,blue,black) )! activatechooseend
auto={20}{UB}:name(X=20) activatechooseacolor all(*[zpos<=20]|opponentLibrary) moveto(exile) and!( if cantargetcard(*[chosencolor]|*) then token(Faerie Rogue,Creature Faerie Rogue,1/1,flying,blue,black) )! activatechooseend
text=Flying -- {X}{UB}: Choose a color. Target opponent exiles the top X cards of his or her library. For each card of the chosen color exiled this way, put a 1/1 blue and black Faerie Rogue creature token with flying onto the battlefield.
mana={3}{UB}{UB}{UB}
type=Legendary Creature
@@ -105156,7 +105171,7 @@ type=Sorcery
[/card]
[card]
name=Sigarda, Heron's Grace
abilities=flying,playershroud
abilities=flying,controllershroud
auto=lord(human|mybattlefield) opponentshroud
auto={2}{E(*|mygraveyard)}:token(Human Soldier,Creature Human Soldier,1/1,white)
text=Flying -- You and Humans you control have hexproof. -- {2}, Exile a card from your graveyard: Put a 1/1 white Human Soldier creature token onto the battlefield.
@@ -134991,7 +135006,7 @@ type=Enchantment
[/card]
[card]
name=Witchbane Orb
abilities=playershroud
abilities=controllershroud
auto=destroy all(mycurses)
text=When Witchbane Orb enters the battlefield, destroy all Curses attached to you. -- You have hexproof.
mana={4}

View File

@@ -2809,7 +2809,7 @@ subtype=Teyo
[/card]
[card]
name=Teyo, the Shieldmage
abilities=playershroud
abilities=controllershroud
auto=counter(0/0,5,loyalty)
auto={C(0/0,-2,Loyalty)}:name(-2: Create a 0/3 Wall with defender) create(Wall:Creature Wall:0/3:white:defender)
text=You have hexproof. (You can't be the target of spells or abilities your opponents control.) -- -2: Create a 0/3 white Wall creature token with defender.

View File

@@ -46,6 +46,7 @@ public:
CHEATMODEAIDECK,
SHOWBORDER,
BLKBORDER,
SORTINGDECKS,
SHOWTOKENS,
SORTINGSETS,
GDVLARGEIMAGE,

View File

@@ -288,6 +288,29 @@ protected:
int color;
};
/**
Matches a card that does not contain a particular color (inclusively).
*/
class WCFilterNotColor: public WCardFilter
{
public:
WCFilterNotColor(int _c)
{
color = _c;
}
;
WCFilterNotColor(string arg);
bool isMatch(MTGCard * c);
string getCode();
float filterFee()
{
return 0.2f;
}
;
protected:
int color;
};
/**
Matches a card that is a particular color (exclusively).
*/

View File

@@ -7782,9 +7782,8 @@ int ATransformer::addToGame()
if(UYNT)
{
if(myCurrentTurn != 1000 && game->turn > myCurrentTurn && source->controller()->getId() == game->currentPlayer->getId())
{
return 1;
}
return 0; // Fixed an issue when the transformation with uynt is triggered by instant/sorcery or by card that left the battlefield before the ability ending turn.
}
return MTGAbility::testDestroy();
}
@@ -7793,6 +7792,7 @@ int ATransformer::destroy()
{
if(aForever)
return 0;
MTGCardInstance * _target = (MTGCardInstance *) target;
if (_target)
{

View File

@@ -161,18 +161,18 @@ void DeckView::renderCard(int index, int alpha, bool asThumbnail, bool griddeckv
if (last_user_activity < 3)
{
int fontAlpha = alpha;
float qtY = cardPosition.y - 135 * cardPosition.scale;
float qtX = cardPosition.x + 40 * cardPosition.scale;
float qtY = cardPosition.y - 115 * cardPosition.scale;
float qtX = cardPosition.x + 62 * cardPosition.scale;
char buffer[4096];
sprintf(buffer, "x%i", deck()->count(cardPosition.card));
WFont * font = mFont;
font->SetScale(1.4f);
font->SetColor(ARGB(fontAlpha/2,0,0,0));
JRenderer::GetInstance()->FillRect(qtX, qtY, font->GetStringWidth(buffer) + 6, 18, ARGB(fontAlpha/2,0,0,0));
JRenderer::GetInstance()->DrawRect(qtX, qtY, font->GetStringWidth(buffer) + 6, 18, ARGB(fontAlpha/2,240,240,240));
font->DrawString(buffer, qtX + 5, qtY + 3);
JRenderer::GetInstance()->FillRect(qtX, qtY, font->GetStringWidth(buffer) + 6, 15, ARGB(fontAlpha/2,0,0,0));
JRenderer::GetInstance()->DrawRect(qtX, qtY, font->GetStringWidth(buffer) + 6, 15, ARGB(fontAlpha/2,240,240,240));
font->DrawString(buffer, qtX + 5, qtY + 0);
font->SetColor(ARGB(fontAlpha,255,255,255));
font->DrawString(buffer, qtX + 4, qtY + 2);
font->DrawString(buffer, qtX + 4, qtY - 1);
font->SetColor(ARGB(255,255,255,255));
font->SetScale(1.0f);
}

View File

@@ -22,6 +22,7 @@ const string Options::optionNames[] = {
"cheatmodedecks",
"ShowBorder",
"BlackBorder",
"SortDecksByDate",
"ShowTokens",
"SortingSets",
"GDVLargeImages",

View File

@@ -94,10 +94,13 @@ vector<DeckMetaData *> GameState::BuildDeckList(const string& path, const string
}
meta = NULL;
}
// Now decks can be sorted by name or by creation date.
if(!options[Options::SORTINGDECKS].number)
std::sort(retList.begin(), retList.end(), sortByName); // Ordered by name from A to Z.
else
std::reverse(retList.begin(), retList.end()); // Ordered by creation date from the last to the first one (e.g. we consider deck2.txt newer than deck1.txt).
std::sort(retList.begin(), retList.end(), sortByName);
return retList;
}
// build a menu with the given deck list and return a vector of the deck ids created.

View File

@@ -893,9 +893,9 @@ void GameStateDeckViewer::renderOnScreenBasicInfo()
float w = mFont->GetStringWidth(buffer);
PIXEL_TYPE backupColor = mFont->GetColor();
renderer->FillRoundRect(SCREEN_WIDTH - (w + 27), y + 5, w + 10, 15, 5, ARGB(hudAlpha/2,0,0,0));
renderer->FillRoundRect(SCREEN_WIDTH - (w + 27), y, w + 5, 4, 5, ARGB(hudAlpha/2,0,0,0));
mFont->SetColor(ARGB(hudAlpha,255,255,255));
mFont->DrawString(buffer, SCREEN_WIDTH - 22, y + 15, JGETEXT_RIGHT);
mFont->DrawString(buffer, SCREEN_WIDTH - 20, y + 1, JGETEXT_RIGHT);
mFont->SetColor(backupColor);
if (mView->filter() != 0) renderer->RenderQuad(mIcons[mView->filter() - 1].get(), SCREEN_WIDTH - 10, y + 15, 0.0f, 0.5, 0.5);

View File

@@ -63,6 +63,8 @@ void GameStateOptions::Start()
optionsList->Add(NEW OptionInteger(Options::SHOWBORDER, "Show Borders"));
//black border
optionsList->Add(NEW OptionInteger(Options::BLKBORDER, "All Black Borders"));
//Sort deck by date
optionsList->Add(NEW OptionInteger(Options::SORTINGDECKS, "Sort decks by date"));
//show tokens in editor
optionsList->Add(NEW OptionInteger(Options::SHOWTOKENS, "Show Tokens in Editor"));
WDecoStyled * wMisc = NEW WDecoStyled(NEW WGuiHeader("Warning!!!"));

View File

@@ -266,6 +266,8 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan
case 'p' :
{
SAFE_DELETE(tc);
if (value.find("power") != string::npos) // Fix to avoid crash on ManaCost parse (e.g. Filter by mana producer).
break;
size_t start = value.find("(");
size_t end = value.rfind(")");
string manaType = value.substr(start + 1, end - start - 1);
@@ -298,6 +300,8 @@ ManaCost * ManaCost::parseManaCost(string s, ManaCost * _manaCost, MTGCardInstan
break;
case 'c': //Counters or cycle
{
if (value.find("compare(") != string::npos) // Fix to avoid crash on ManaCost parse (e.g. Filter by mana producer).
break;
if (value.find("convoke") != string::npos)
{
if (!tc)

View File

@@ -12,10 +12,12 @@ WCFilterFactory* WCFilterFactory::GetInstance()
if (!me) me = NEW WCFilterFactory();
return me;
}
void WCFilterFactory::Destroy()
{
SAFE_DELETE(me);
}
size_t WCFilterFactory::findNext(string src, size_t start, char open, char close)
{
int num = 0;
@@ -30,6 +32,7 @@ size_t WCFilterFactory::findNext(string src, size_t start, char open, char close
}
return string::npos;
}
WCardFilter * WCFilterFactory::Construct(string src)
{
size_t x = 0;
@@ -152,6 +155,8 @@ WCardFilter * WCFilterFactory::Terminal(string src, string arg)
return NEW WCFilterRarity(arg);
else if (type == "c" || type == "color")
return NEW WCFilterColor(arg);
else if (type == "nc" || type == "ncolor")
return NEW WCFilterNotColor(arg);
else if (type == "xc" || type == "xcolor")
return NEW WCFilterOnlyColor(arg);
else if (type == "s" || type == "set")
@@ -172,6 +177,7 @@ WCardFilter * WCFilterFactory::Terminal(string src, string arg)
return NEW WCFilterNULL();
}
//WCFilterLetter
WCFilterLetter::WCFilterLetter(string arg)
{
@@ -180,6 +186,7 @@ WCFilterLetter::WCFilterLetter(string arg)
else
alpha = tolower(arg[0]);
}
bool WCFilterLetter::isMatch(MTGCard * c)
{
if (!c || !c->data) return false;
@@ -188,12 +195,14 @@ bool WCFilterLetter::isMatch(MTGCard * c)
if (s[0] == alpha || (alpha == '#' && (isdigit(s[0]) || ispunct(s[0])))) return true;
return false;
}
string WCFilterLetter::getCode()
{
char buf[24];
sprintf(buf, "alpha:%c;", alpha);
return buf;
}
//WCFilterSet
WCFilterSet::WCFilterSet(string arg)
{
@@ -208,7 +217,6 @@ string WCFilterSet::getCode()
sprintf(buf, "set:%s;", setName.c_str());
return buf;
}
;
//WCFilterColor
bool WCFilterColor::isMatch(MTGCard * c)
@@ -216,15 +224,16 @@ bool WCFilterColor::isMatch(MTGCard * c)
if (!c || !c->data) return false;
return (c->data->hasColor(color));
}
string WCFilterColor::getCode()
{
char buf[12];
char c = '?';
if (color < 0 || color >= Constants::NB_Colors) c = Constants::MTGColorChars[color];
if (color >= 0 && color < Constants::NB_Colors) c = Constants::MTGColorChars[color];
sprintf(buf, "color:%c;", c);
return buf;
}
;
WCFilterColor::WCFilterColor(string arg)
{
color = -1;
@@ -238,6 +247,57 @@ WCFilterColor::WCFilterColor(string arg)
}
}
}
//WCFilterNotColor
bool WCFilterNotColor::isMatch(MTGCard * c)
{
if (!c || !c->data) return false;
if(color == -1){ // Only multicolored cards
for (int i = 1; i < 6; i++){
if(c->data->hasColor(i)){
for (int j = i+1; j < 6; j++){
if(c->data->hasColor(j))
return true;
}
}
}
return false;
} else if(color == 0){ // Not colorless cards
for (int i = 1; i < 6; i++){
if(c->data->hasColor(i))
return true;
}
return false;
} else
return !(c->data->hasColor(color));
}
string WCFilterNotColor::getCode()
{
char buf[12];
char c = '?';
if (color >= 0 && color < Constants::NB_Colors)
c = Constants::MTGColorChars[color];
else if (color < 0)
c = 'm';
sprintf(buf, "ncolor:%c;", c);
return buf;
}
WCFilterNotColor::WCFilterNotColor(string arg)
{
color = -1;
char c = tolower(arg[0]);
for (int i = 0; i < Constants::NB_Colors; i++)
{
if (Constants::MTGColorChars[i] == c)
{
color = i;
break;
}
}
}
//WCFilterOnlyColor
bool WCFilterOnlyColor::isMatch(MTGCard * c)
{
@@ -249,14 +309,16 @@ bool WCFilterOnlyColor::isMatch(MTGCard * c)
}
return (c->data->hasColor(color));
}
string WCFilterOnlyColor::getCode()
{
char buf[12];
char c = '?';
if (color < 0 || color >= Constants::NB_Colors) c = Constants::MTGColorChars[color];
if (color >= 0 && color < Constants::NB_Colors) c = Constants::MTGColorChars[color];
sprintf(buf, "xcolor:%c;", c);
return buf;
}
//WCFilterProducesColor
bool WCFilterProducesColor::isMatch(MTGCard * c)
{
@@ -271,23 +333,27 @@ bool WCFilterProducesColor::isMatch(MTGCard * c)
return true;
//Retrieve non basic Mana abilities
string s = c->data->magicText;
size_t t = s.find("add{");
while (t != string::npos)
{
s = s.substr(t + 3);
ManaCost * mc = ManaCost::parseManaCost(s);
if (mc->hasColor(color) > 0)
vector<string> rows = split(c->data->magicText, '\n'); // Now the parser analyze the full card text row by row to avoid fake color matches.
for(size_t j = 0; j < rows.size(); j++){
string s = rows[j];
size_t t = s.find("add{");
while (t != string::npos)
{
bMatch = true;
s = s.substr(t + 3);
ManaCost * mc = ManaCost::parseManaCost(s);
if (mc->hasColor(color) > 0)
{
bMatch = true;
SAFE_DELETE(mc);
break;
}
SAFE_DELETE(mc);
break;
t = s.find("add{");
}
SAFE_DELETE(mc);
t = s.find("add");
}
return bMatch;
}
string WCFilterProducesColor::getCode()
{
char buf[12];
@@ -296,11 +362,13 @@ string WCFilterProducesColor::getCode()
sprintf(buf, "produces:%c;", c);
return buf;
}
//WCFilterNumeric
WCFilterNumeric::WCFilterNumeric(string arg)
{
number = atoi(arg.c_str());
}
//WCFilterCMC
bool WCFilterCMC::isMatch(MTGCard * c)
{
@@ -315,30 +383,35 @@ string WCFilterCMC::getCode()
sprintf(buf, "cmc:%i;", number);
return buf;
}
//WCFilterPower
bool WCFilterPower::isMatch(MTGCard * c)
{
if (!c || !c->data) return false;
return (c->data->getPower() == number);
}
string WCFilterPower::getCode()
{
char buf[64];
sprintf(buf, "power:%i;", number);
return buf;
}
//WCFilterPower
bool WCFilterToughness::isMatch(MTGCard * c)
{
if (!c || !c->data) return false;
return (c->data->getToughness() == number);
}
string WCFilterToughness::getCode()
{
char buf[64];
sprintf(buf, "toughness:%i;", number);
return buf;
}
//WCFilterRarity
float WCFilterRarity::filterFee()
{
@@ -355,12 +428,14 @@ float WCFilterRarity::filterFee()
}
return 0.0f;
}
bool WCFilterRarity::isMatch(MTGCard * c)
{
if (!c || !c->data) return false;
if (rarity == 'A') return true; //A for "Any" or "All"
return (c->getRarity() == rarity);
}
string WCFilterRarity::getCode()
{
char buf[64];
@@ -393,7 +468,7 @@ string WCFilterRarity::getCode()
sprintf(buf, "rarity:%s;", rarities[x]);
return buf;
}
;
WCFilterRarity::WCFilterRarity(string arg)
{
rarity = -1;
@@ -412,6 +487,7 @@ WCFilterRarity::WCFilterRarity(string arg)
}
rarity = 'A';
}
//WCFilterAbility
bool WCFilterAbility::isMatch(MTGCard * c)
{
@@ -433,6 +509,7 @@ WCFilterAbility::WCFilterAbility(string arg)
}
ability = -1;
}
string WCFilterAbility::getCode()
{
char buf[64];
@@ -440,7 +517,6 @@ string WCFilterAbility::getCode()
sprintf(buf, "ability:%s;", Constants::MTGBasicAbilities[ability]);
return buf;
}
;
float WCFilterAbility::filterFee()
{
@@ -487,22 +563,26 @@ float WCFilterAbility::filterFee()
}
return 0.0f;
}
//WCFilterType
bool WCFilterType::isMatch(MTGCard * c)
{
return c->data->hasType(type.c_str());
}
string WCFilterType::getCode()
{
char buf[4068];
sprintf(buf, "type:%s;", type.c_str());
return buf;
}
//Misc. filter code
float WCFilterAND::filterFee()
{
return lhs->filterFee() + rhs->filterFee();
}
float WCFilterOR::filterFee()
{
float lFee = lhs->filterFee();
@@ -511,12 +591,14 @@ float WCFilterOR::filterFee()
return lFee;
return rFee;
}
string WCFilterNOT::getCode()
{
char buf[4068];
sprintf(buf, "{%s}", kid->getCode().c_str());
return buf;
}
string WCFilterGROUP::getCode()
{
char buf[4068];
@@ -530,6 +612,7 @@ string WCFilterAND::getCode()
sprintf(buf, "%s&%s", lhs->getCode().c_str(), rhs->getCode().c_str());
return buf;
}
string WCFilterOR::getCode()
{
char buf[4068];
@@ -543,4 +626,3 @@ bool WCFilterOR::isMatch(MTGCard *c)
if (rhs->isMatch(c)) return true;
return false;
}
;

View File

@@ -2186,6 +2186,13 @@ void WGuiFilterItem::updateValue()
mParent->addArg("Exclusively Black", "xc:b;");
mParent->addArg("Exclusively Red", "xc:r;");
mParent->addArg("Exclusively Green", "xc:g;");
mParent->addArg("Not White", "nc:w;");
mParent->addArg("Not Blue", "nc:u;");
mParent->addArg("Not Black", "nc:b;");
mParent->addArg("Not Red", "nc:r;");
mParent->addArg("Not Green", "nc:g;");
mParent->addArg("Not Colorless", "nc:x;");
mParent->addArg("Only Multicolored", "nc:m;");
}
else if (filterType == FILTER_PRODUCE)
{