Block Cost Rule

Update rules folder
This commit is contained in:
Anthony Calosa
2016-06-15 22:26:55 +08:00
parent a2249a7392
commit b38275123a
14 changed files with 238 additions and 43 deletions

View File

@@ -18,6 +18,7 @@ auto=overloadrule
auto=attackrule
auto=attackcostrule
auto=blockrule
auto=blockcostrule
auto=combattriggerrule
auto=legendrule
auto=planeswalkerrule

View File

@@ -17,6 +17,7 @@ auto=overloadrule
auto=attackrule
auto=attackcostrule
auto=blockrule
auto=blockcostrule
auto=combattriggerrule
auto=legendrule
auto=planeswalkerrule

View File

@@ -21,6 +21,7 @@ auto=overloadrule
auto=attackrule
auto=attackcostrule
auto=blockrule
auto=blockcostrule
auto=combattriggerrule
auto=legendrule
auto=planeswalkerrule

View File

@@ -1,17 +1,4 @@
grade=borderline
#planeswalker and creature attack cost...
[card]
name=Archangel of Tithes
abilities=flying
auto=this(untapped) lord(creature|opponentbattlefield) transforms((,newability[@each mycombatbegins:pay[[{1}]] name(pay 1 mana) donothing?cantattack all(this)]))
auto=@combat(attacking) source(this):all(creature|opponentbattlefield) transforms((,newability[pay[[{1}]] name(pay 1 mana) donothing?cantblock all(this)]))
text=Flying -- As long as Archangel of Tithes is untapped, creatures can't attack you or a planeswalker you control unless their controller pays {1} for each of those creatures. -- As long as Archangel of Tithes is attacking, creatures can't block unless their controller pays {1} for each of those creatures.
mana={1}{W}{W}{W}
type=Creature
subtype=Angel
power=3
toughness=5
[/card]
[card]
name=Autumn Willow
abilities=opponentshroud,shroud

View File

@@ -4290,6 +4290,18 @@ power=5
toughness=5
[/card]
[card]
name=Archangel of Tithes
abilities=flying
auto=this(untapped) lord(creature|opponentbattlefield) transforms((,newability[attackpwcost:1]))
auto=this(attacking) lord(creature|opponentbattlefield) transforms((,newability[blockcost:1]))
text=Flying -- As long as Archangel of Tithes is untapped, creatures can't attack you or a planeswalker you control unless their controller pays {1} for each of those creatures. -- As long as Archangel of Tithes is attacking, creatures can't block unless their controller pays {1} for each of those creatures.
mana={1}{W}{W}{W}
type=Creature
subtype=Angel
power=3
toughness=5
[/card]
[card]
name=Archangel of Thune
abilities=flying,lifelink
auto=@lifeof(player):all(creature|mybattlefield) counter(1/1,1)
@@ -18359,6 +18371,17 @@ mana={3}{G}{G}{W}
type=Enchantment
[/card]
[card]
name=Collective Restraint
auto=aslongas(forest|mybattlefield) lord(creature|opponentbattlefield) transforms((,newability[attackcost:1]))
auto=aslongas(island|mybattlefield) lord(creature|opponentbattlefield) transforms((,newability[attackcost:1]))
auto=aslongas(mountain|mybattlefield) lord(creature|opponentbattlefield) transforms((,newability[attackcost:1]))
auto=aslongas(swamp|mybattlefield) lord(creature|opponentbattlefield) transforms((,newability[attackcost:1]))
auto=aslongas(plains|mybattlefield) lord(creature|opponentbattlefield) transforms((,newability[attackcost:1]))
text=Domain — Creatures can't attack you unless their controller pays {X} for each creature he or she controls that's attacking you, where X is the number of basic land types among lands you control.
mana={3}{U}
type=Enchantment
[/card]
[card]
name=Collective Unconscious
auto=foreach(creature|myBattlefield)draw:1
text=Draw a card for each creature you control.
@@ -112257,11 +112280,10 @@ power=3
toughness=6
[/card]
[card]
name=War Dance
auto=@each my upkeep:may counter(0/0,1,Verse)
auto={S}:thisforeach(counter{0/0.1.Verse}) 1/1 target(creature)
text=At the beginning of your upkeep, you may put a verse counter on War Dance. -- Sacrifice War Dance: Target creature gets +X/+X until end of turn, where X is the number of verse counters on War Dance.
mana={G}
name=War Cadence
auto={X}{U}:name(Block X Cost) thisforeach(X) all(creature) transforms((,newability[blockcost:1])) ueot
text={X}{R}: This turn, creatures can't block unless their controller pays {X} for each blocking creature he or she controls.
mana={2}{R}
type=Enchantment
[/card]
[card]
@@ -112272,6 +112294,14 @@ mana={3}
type=Artifact
[/card]
[card]
name=War Dance
auto=@each my upkeep:may counter(0/0,1,Verse)
auto={S}:thisforeach(counter{0/0.1.Verse}) 1/1 target(creature)
text=At the beginning of your upkeep, you may put a verse counter on War Dance. -- Sacrifice War Dance: Target creature gets +X/+X until end of turn, where X is the number of verse counters on War Dance.
mana={G}
type=Enchantment
[/card]
[card]
name=War Elemental
auto=this(opponentdamagecount < 1) aslongas(War Elemental|mybattlefield) sacrifice oneshot
auto=@damagefoeof(player):may all(trigger[to]) dynamicability<!myfoe thatmuchcountersoneone tosrc!>
@@ -112348,6 +112378,13 @@ mana={3}{W}
type=Instant
[/card]
[card]
name=War Tax
auto={X}{U}:name(Attack X Cost) thisforeach(X) all(creature) transforms((,newability[attackcost:1])) ueot
text={X}{U}: This turn, creatures can't attack unless their controller pays {X} for each attacking creature he or she controls.
mana={2}{U}
type=Enchantment
[/card]
[card]
name=War-Name Aspirant
auto=if raid then counter(1/1,1)
auto=cantbeblockedby(creature[power<=1])

View File

@@ -3770,12 +3770,6 @@ mana={3}{G}
type=Instant
[/card]
[card]
name=Collective Restraint
text=Domain — Creatures can't attack you unless their controller pays {X} for each creature he or she controls that's attacking you, where X is the number of basic land types among lands you control.
mana={3}{U}
type=Enchantment
[/card]
[card]
name=Collective Voyage
text=Join forces — Starting with you, each player may pay any amount of mana. Each player searches his or her library for up to X basic land cards, where X is the total amount of mana paid this way, puts them onto the battlefield tapped, then shuffles his or her library.
mana={G}
@@ -25525,12 +25519,6 @@ mana={4}
type=Artifact
[/card]
[card]
name=War Cadence
text={X}{R}: This turn, creatures can't block unless their controller pays {X} for each blocking creature he or she controls.
mana={2}{R}
type=Enchantment
[/card]
[card]
name=War Elephant
text=Trample; banding (Any creatures with banding, and up to one without, can attack in a band. Bands are blocked as a group. If any creatures with banding you control are blocking or being blocked by a creature, you divide that creature's combat damage, not its controller, among any of the creatures it's being blocked by or is blocking.)
mana={3}{W}
@@ -25540,12 +25528,6 @@ power=2
toughness=2
[/card]
[card]
name=War Tax
text={X}{U}: This turn, creatures can't attack unless their controller pays {X} for each attacking creature he or she controls.
mana={2}{U}
type=Enchantment
[/card]
[card]
name=Warbringer
text=Dash costs you pay cost {2} less (as long as this creature is on the battlefield). -- Dash {2}{R} (You may cast this spell for its dash cost. If you do, it gains haste, and it's returned from the battlefield to its owner's hand at the beginning of the next end step.)
mana={3}{R}

View File

@@ -4868,7 +4868,8 @@ class AAttackSetCost: public MTGAbility
{
public:
string number;
AAttackSetCost(GameObserver* observer, int _id, MTGCardInstance * _source, string number);
bool pw;
AAttackSetCost(GameObserver* observer, int _id, MTGCardInstance * _source, string number, bool pw = false);
void Update(float dt);
int addToGame();
int destroy();
@@ -4876,6 +4877,19 @@ public:
AAttackSetCost * clone() const;
};
//ABlockSetCost
class ABlockSetCost: public MTGAbility
{
public:
string number;
ABlockSetCost(GameObserver* observer, int _id, MTGCardInstance * _source, string number);
void Update(float dt);
int addToGame();
int destroy();
const string getMenuText();
ABlockSetCost * clone() const;
};
//ABlink
class ABlink: public MTGAbility
{

View File

@@ -217,7 +217,7 @@ public:
OVERLOAD_COST = 34,
BESTOW_COST = 35,
ATTACK_COST = 36,
ATTACKPLANESWALKER_COST = 37,
BLOCK_COST = 37,
};
};

View File

@@ -261,6 +261,9 @@ public:
int attackCost;
int attackCostBackup;
int attackPlaneswalkerCost;
int attackPlaneswalkerCostBackup;
int blockCost;
int blockCostBackup;
int imprintG;
int imprintU;
int imprintR;

View File

@@ -286,6 +286,18 @@ public:
virtual MTGCombatTriggersRule * clone() const;
};
class MTGBlockCostRule: public PermanentAbility
{
public:
string scost;
int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL);
int reactToClick(MTGCardInstance * card);
virtual ostream& toString(ostream& out) const;
MTGBlockCostRule(GameObserver* observer, int _id);
const string getMenuText();
virtual MTGBlockCostRule * clone() const;
};
class MTGBlockRule: public PermanentAbility
{
public:

View File

@@ -5372,8 +5372,8 @@ APhaseActionGeneric::~APhaseActionGeneric()
}
//AAttackSetCost
AAttackSetCost::AAttackSetCost(GameObserver* observer, int _id, MTGCardInstance * _source, string number) :
MTGAbility(observer, _id, _source), number(number)
AAttackSetCost::AAttackSetCost(GameObserver* observer, int _id, MTGCardInstance * _source, string number, bool pw) :
MTGAbility(observer, _id, _source), number(number), pw(pw)
{
}
@@ -5382,6 +5382,8 @@ void AAttackSetCost::Update(float dt)
if(game->getCurrentGamePhase() != MTG_PHASE_COMBATATTACKERS)
{
source->attackCost = source->attackCostBackup;
if(pw)
source->attackPlaneswalkerCost = source->attackPlaneswalkerCostBackup;
MTGAbility::Update(dt);
}
}
@@ -5391,6 +5393,11 @@ int AAttackSetCost::addToGame()
WParsedInt attackcost(number, NULL, source);
source->attackCost += attackcost.getValue();
source->attackCostBackup += attackcost.getValue();
if(pw)
{
source->attackPlaneswalkerCost += attackcost.getValue();
source->attackPlaneswalkerCostBackup += attackcost.getValue();
}
return MTGAbility::addToGame();
}
@@ -5401,6 +5408,11 @@ int AAttackSetCost::destroy()
WParsedInt attackcost(number, NULL, source);
source->attackCost -= attackcost.getValue();
source->attackCostBackup -= attackcost.getValue();
if(pw)
{
source->attackPlaneswalkerCost -= attackcost.getValue();
source->attackPlaneswalkerCostBackup -= attackcost.getValue();
}
return 1;
}
@@ -5415,6 +5427,49 @@ AAttackSetCost * AAttackSetCost::clone() const
return NEW AAttackSetCost(*this);
}
//ABlockSetCost
ABlockSetCost::ABlockSetCost(GameObserver* observer, int _id, MTGCardInstance * _source, string number) :
MTGAbility(observer, _id, _source), number(number)
{
}
void ABlockSetCost::Update(float dt)
{
if(game->getCurrentGamePhase() != MTG_PHASE_COMBATBLOCKERS)
{
source->blockCost = source->blockCostBackup;
MTGAbility::Update(dt);
}
}
int ABlockSetCost::addToGame()
{
WParsedInt blockCost(number, NULL, source);
source->blockCost += blockCost.getValue();
source->blockCostBackup += blockCost.getValue();
return MTGAbility::addToGame();
}
int ABlockSetCost::destroy()
{
WParsedInt blockCost(number, NULL, source);
source->blockCost -= blockCost.getValue();
source->blockCostBackup -= blockCost.getValue();
return 1;
}
const string ABlockSetCost::getMenuText()
{
return "Block Cost";
}
ABlockSetCost * ABlockSetCost::clone() const
{
return NEW ABlockSetCost(*this);
}
//a blink
ABlink::ABlink(GameObserver* observer, int _id, MTGCardInstance * card, MTGCardInstance * _target, bool blinkueot, bool blinkForSource, bool blinkhand, MTGAbility * stored) :

View File

@@ -1193,6 +1193,13 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
observer->addObserver(NEW MTGBlockRule(observer, -1));
return NULL;
}
//this rule handles blocking cost ability during blocker phase
found = s.find("blockcostrule");
if(found != string::npos)
{
observer->addObserver(NEW MTGBlockCostRule(observer, -1));
return NULL;
}
//this rule handles cards that have soulbond
found = s.find("soulbondrule");
if(found != string::npos)
@@ -2842,6 +2849,18 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
return NEW AAttackSetCost(observer, id, card, s.substr(11));
}
//attack cost + planeswalker
if (s.find("attackpwcost:") != string::npos)
{
return NEW AAttackSetCost(observer, id, card, s.substr(13),true);
}
//block cost
if (s.find("blockcost:") != string::npos)
{
return NEW ABlockSetCost(observer, id, card, s.substr(10));
}
//flanking
if (s.find("flanker") != string::npos)
{

View File

@@ -212,6 +212,9 @@ void MTGCardInstance::initMTGCI()
attackCost = 0;
attackCostBackup = 0;
attackPlaneswalkerCost = 0;
attackPlaneswalkerCostBackup = 0;
blockCost = 0;
blockCostBackup = 0;
imprintG = 0;
imprintU = 0;
imprintR = 0;

View File

@@ -1348,6 +1348,7 @@ MTGOverloadRule * MTGOverloadRule::clone() const
///////////////////////////////////////////////////////////////////////////////////////////////////
//ATTACK COST
MTGAttackCostRule::MTGAttackCostRule(GameObserver* observer, int _id) :
PermanentAbility(observer, _id)
{
@@ -1387,9 +1388,17 @@ int MTGAttackCostRule::reactToClick(MTGCardInstance * card)
ManaCost * attackcost = NEW ManaCost(ManaCost::parseManaCost("{0}",NULL,NULL));
attackcost->add(0,card->attackCostBackup);
ManaCost * playerMana = player->getManaPool();
playerMana->pay(attackcost);
playerMana->pay(attackcost);//I think you can't pay partial cost to attack cost so you pay full (508.1i)
card->attackCost = 0;
card->attackPlaneswalkerCost = 0;
return 1;
/*
508.1g: If any of the chosen creatures require paying costs to attack, the active player determines the total cost to attack.
Costs may include paying mana, tapping permanents, sacrificing permanents, discarding cards, and so on. Once the total cost is determined, it becomes “locked in.”
If effects would change the total cost after this time, ignore this change.
508.1h: If any of the costs require mana, the active player then has a chance to activate mana abilities (see rule 605, “Mana Abilities”).
508.1i: Once the player has enough mana in his or her mana pool, he or she pays all costs in any order. Partial payments are not allowed.
*/
}
ostream& MTGAttackCostRule::toString(ostream& out) const
@@ -1409,6 +1418,77 @@ MTGAttackCostRule * MTGAttackCostRule::clone() const
return NEW MTGAttackCostRule(*this);
}
//BLOCK COST
MTGBlockCostRule::MTGBlockCostRule(GameObserver* observer, int _id) :
PermanentAbility(observer, _id)
{
aType = MTGAbility::BLOCK_COST;
scost = "Pay to block";
}
int MTGBlockCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *)
{
if (currentPhase == MTG_PHASE_COMBATBLOCKERS && !game->isInterrupting
&& card->controller() != game->currentPlayer
)
{
if(card->isPhased)
return 0;
if(card->blockCost < 1)
return 0;
ManaCost * playerMana = card->controller()->getManaPool();
ManaCost * blockcost = NEW ManaCost(ManaCost::parseManaCost("{0}",NULL,NULL));
blockcost->add(0,card->blockCostBackup);
if(blockcost->extraCosts)
for(unsigned int i = 0; i < blockcost->extraCosts->costs.size();i++)
{
blockcost->extraCosts->costs[i]->setSource(card);
}
scost = blockcost->getConvertedCost();
if (playerMana->canAfford(blockcost))
return 1;
}
return 0;
}
int MTGBlockCostRule::reactToClick(MTGCardInstance * card)
{
if (!isReactingToClick(card))
return 0;
Player * player = game->currentlyActing();
ManaCost * blockcost = NEW ManaCost(ManaCost::parseManaCost("{0}",NULL,NULL));
blockcost->add(0,card->blockCostBackup);
ManaCost * playerMana = player->getManaPool();
playerMana->pay(blockcost);//I think you can't pay partial cost to block cost so you pay full (509.1f)
card->blockCost = 0;
return 1;
/*
509.1d: If any of the chosen creatures require paying costs to block, the defending player determines the total cost to block.
Costs may include paying mana, tapping permanents, sacrificing permanents, discarding cards, and so on.
Once the total cost is determined, it becomes “locked in.” If effects would change the total cost after this time, ignore this change.
509.1e: If any of the costs require mana, the defending player then has a chance to activate mana abilities (see rule 605, “Mana Abilities”).
509.1f: Once the player has enough mana in his or her mana pool, he or she pays all costs in any order. Partial payments are not allowed.
*/
}
ostream& MTGBlockCostRule::toString(ostream& out) const
{
out << "MTGBlockCostRule ::: (";
return MTGAbility::toString(out) << ")";
}
const string MTGBlockCostRule::getMenuText()
{
sprintf(menuText, "Pay to block");
return menuText;
}
MTGBlockCostRule * MTGBlockCostRule::clone() const
{
return NEW MTGBlockCostRule(*this);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
bool MTGAttackRule::select(Target* t)
{
@@ -1780,7 +1860,7 @@ int MTGBlockRule::receiveEvent(WEvent *e)
{
MTGCardInstance * card = z->cards[i];
if ((card->defenser && !card->defenser->has(Constants::LURE))||!card->defenser)
if(card->canBlock(lurer))
if(card->canBlock(lurer) && card->blockCost < 1)
card->setDefenser(lurer);
//force a block on a lurer, the player has a chance to set his own choice on multiple lures
//but this action can not be ignored.
@@ -1798,7 +1878,7 @@ int MTGBlockRule::isReactingToClick(MTGCardInstance * card, ManaCost *)
&& card->controller() != game->currentPlayer
)
{
if (card->canBlock() && !card->isPhased)
if (card->canBlock() && !card->isPhased && card->blockCost < 1)
{
if(card->isDefenser())
blockmenu = "Remove Blocker";