added stack check, modified life check
if activating ability, playing a land or casting sorcery spell at sorcery level(timing restriction), if the stack is not empty, don't allow it. Modified the life state check, if any of the players would lose the game, allow the gamestateeffects to check... added reduceto:value for ali from cairo...
This commit is contained in:
@@ -2168,7 +2168,7 @@ toughness=1
|
||||
[/card]
|
||||
[card]
|
||||
name=Ali from Cairo
|
||||
auto=@damaged(controller) restriction{compare(lifetotal)~lessthan~1}:this(controllerlife < 1) lifeset:1 controller
|
||||
auto=this(controllerlife >= 1) transforms((,newability[reduceto:1]))
|
||||
text=Damage that would reduce your life total to less than 1 reduces it to 1 instead.
|
||||
mana={2}{R}{R}
|
||||
type=Creature
|
||||
@@ -28928,7 +28928,7 @@ toughness=6
|
||||
name=Elderscale Wurm
|
||||
abilities=trample
|
||||
auto=if compare(lifetotal)~lessthan~7 then lifeset:7 controller
|
||||
auto=this(controllerlife > 6) transforms((,newability[@damaged(controller):if compare(lifetotal)~lessthan~7 then lifeset:7 controller]))
|
||||
auto=this(controllerlife >= 7) transforms((,newability[reduceto:7]))
|
||||
text=Trample. -- When Elderscale Wurm enters the battlefield, if your life total is less than 7, your life total becomes 7. -- As long as you have 7 or more life, damage that would reduce your life total to less than 7 reduces it to 7 instead.
|
||||
mana={4}{G}{G}{G}
|
||||
type=Creature
|
||||
@@ -36160,7 +36160,7 @@ toughness=3
|
||||
name=Fortune Thief
|
||||
facedown={3}
|
||||
autofacedown={R}{R}:morph
|
||||
auto=@damaged(controller) restriction{compare(lifetotal)~lessthan~1}:this(controllerlife < 1) lifeset:1 controller
|
||||
auto=this(controllerlife >= 1) transforms((,newability[reduceto:1]))
|
||||
text=Damage that would reduce your life total to less than 1 reduces it to 1 instead. -- Morph {R}{R} (You may cast this face down as a 2/2 creature for {3}. Turn it face up any time for its morph cost.)
|
||||
mana={4}{R}
|
||||
type=Creature
|
||||
@@ -98227,6 +98227,17 @@ power=2
|
||||
toughness=3
|
||||
[/card]
|
||||
[card]
|
||||
name=Sustaining Spirit
|
||||
auto=cumulativeupcost[{1}{W}] sacrifice
|
||||
auto=this(controllerlife >= 1) transforms((,newability[reduceto:1]))
|
||||
text=Cumulative upkeep {1}{W} (At the beginning of your upkeep, put an age counter on this permanent, then sacrifice it unless you pay its upkeep cost for each age counter on it.) -- Damage that would reduce your life total to less than 1 reduces it to 1 instead.
|
||||
mana={1}{W}
|
||||
type=Creature
|
||||
subtype=Angel Spirit
|
||||
power=0
|
||||
toughness=3
|
||||
[/card]
|
||||
[card]
|
||||
name=Sustenance
|
||||
auto={1}{S(land|myBattlefield)}:1/1 target(creature)
|
||||
text={1}, Sacrifice a land: Target creature gets +1/+1 until end of turn.
|
||||
@@ -114654,6 +114665,13 @@ mana={3}
|
||||
type=Artifact
|
||||
[/card]
|
||||
[card]
|
||||
name=Worship
|
||||
auto=this(variable{worshipped} >= 1) transforms((,newability[reduceto:1]))
|
||||
text=If you control a creature, damage that would reduce your life total to less than 1 reduces it to 1 instead.
|
||||
mana={3}{W}
|
||||
type=Enchantment
|
||||
[/card]
|
||||
[card]
|
||||
name=Worthy Cause
|
||||
auto=life:storedtoughness controller
|
||||
buyback={W}{2}
|
||||
|
||||
@@ -16201,15 +16201,6 @@ type=Sorcery
|
||||
text=You gain 2 life. Then if you have more life than an opponent, draw a card. Rebound (If you cast this spell from your hand, exile it as it resolves. At the beginning of your next upkeep, you may cast this card from exile without paying its mana cost.)
|
||||
[/card]
|
||||
[card]
|
||||
name=Sustaining Spirit
|
||||
text=Cumulative upkeep {1}{W} (At the beginning of your upkeep, put an age counter on this permanent, then sacrifice it unless you pay its upkeep cost for each age counter on it.) -- Damage that would reduce your life total to less than 1 reduces it to 1 instead.
|
||||
mana={1}{W}
|
||||
type=Creature
|
||||
subtype=Angel Spirit
|
||||
power=0
|
||||
toughness=3
|
||||
[/card]
|
||||
[card]
|
||||
name=Sutured Ghoul
|
||||
text=Trample -- As Sutured Ghoul enters the battlefield, exile any number of creature cards from your graveyard. -- Sutured Ghoul's power is equal to the total power of the exiled cards and its toughness is equal to their total toughness.
|
||||
mana={4}{B}{B}{B}
|
||||
@@ -18718,12 +18709,6 @@ mana={2}{B}{B}{B}
|
||||
type=Enchantment
|
||||
[/card]
|
||||
[card]
|
||||
name=Worship
|
||||
text=If you control a creature, damage that would reduce your life total to less than 1 reduces it to 1 instead.
|
||||
mana={3}{W}
|
||||
type=Enchantment
|
||||
[/card]
|
||||
[card]
|
||||
name=Wort, the Raidmother
|
||||
text=When Wort, the Raidmother enters the battlefield, put two 1/1 red and green Goblin Warrior creature tokens onto the battlefield. -- Each red or green instant or sorcery spell you cast has conspire. (As you cast the spell, you may tap two untapped creatures you control that share a color with it. When you do, copy it and you may choose new targets for the copy.)
|
||||
mana={4}{RG}{RG}
|
||||
|
||||
@@ -688,6 +688,13 @@ private:
|
||||
{
|
||||
intValue = target->controller()->opponent()->game->hand->nb_cards;
|
||||
}
|
||||
else if (s == "worshipped")//Worship
|
||||
{
|
||||
if(card->controller()->game->battlefield->hasType("creature"))
|
||||
intValue = card->controller()->life;
|
||||
else
|
||||
intValue = 0;
|
||||
}
|
||||
else if (s == "pancientooze")//Ancient Ooze
|
||||
{
|
||||
intValue = 0;
|
||||
@@ -5997,6 +6004,37 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
//Reduce to .. Ali from Cairo...
|
||||
class AReduceToAbility: public MTGAbility
|
||||
{
|
||||
public:
|
||||
string life_s;
|
||||
|
||||
AReduceToAbility(GameObserver* observer, int _id, MTGCardInstance * _source, string _life_s) :
|
||||
MTGAbility(observer, _id, _source)
|
||||
{
|
||||
life_s = _life_s;
|
||||
}
|
||||
int receiveEvent(WEvent * event)
|
||||
{
|
||||
if(WEventDamage * isDamaged = dynamic_cast<WEventDamage *> (event))
|
||||
{
|
||||
if (isDamaged->damage->target->type_as_damageable == Damageable::DAMAGEABLE_PLAYER)
|
||||
{
|
||||
Player * p = (Player *) isDamaged->damage->target;
|
||||
WParsedInt lifetoset(life_s, NULL, source);
|
||||
if(p && p == source->controller() && p->life <= lifetoset.getValue())
|
||||
p->life = lifetoset.getValue();
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
AReduceToAbility * clone() const
|
||||
{
|
||||
return NEW AReduceToAbility(*this);
|
||||
}
|
||||
};
|
||||
|
||||
//flanking ability
|
||||
class AFlankerAbility: public MTGAbility
|
||||
{
|
||||
|
||||
@@ -234,9 +234,9 @@ public:
|
||||
void revertbaseP();
|
||||
void revertbaseT();
|
||||
int getCurrentPower();
|
||||
int getCurrentToughness();
|
||||
int LKIpower;
|
||||
int LKItoughness;
|
||||
int getCurrentToughness();
|
||||
void cdaPT(int p = 0, int t = 0);
|
||||
bool isCDA;
|
||||
void switchPT(bool apply = false);
|
||||
@@ -248,6 +248,7 @@ public:
|
||||
bool discarded;
|
||||
int copiedID;
|
||||
int modifiedbAbi;
|
||||
bool StackIsEmptyandSorcerySpeed();
|
||||
|
||||
void eventattacked();
|
||||
void eventattackedAlone();
|
||||
|
||||
@@ -71,7 +71,7 @@ public:
|
||||
ManaPool * getManaPool();
|
||||
void takeMulligan();
|
||||
void serumMulligan();
|
||||
bool DeadLifeState();
|
||||
bool DeadLifeState(bool check = false);
|
||||
ManaCost * doesntEmpty;
|
||||
ManaCost * poolDoesntEmpty;
|
||||
void cleanupPhase();
|
||||
|
||||
@@ -578,6 +578,8 @@ void GameObserver::Update(float dt)
|
||||
{
|
||||
mLayers->actionLayer()->Update(0);
|
||||
}
|
||||
players[0]->DeadLifeState();
|
||||
players[1]->DeadLifeState();
|
||||
gameStateBasedEffects();
|
||||
}
|
||||
oldGamePhase = mCurrentGamePhase;
|
||||
@@ -764,7 +766,7 @@ void GameObserver::gameStateBasedEffects()
|
||||
///////////////////////////////////////////////////////////
|
||||
//life checks/poison checks also checks cant win or lose.//
|
||||
///////////////////////////////////////////////////////////
|
||||
players[i]->DeadLifeState();//refactored
|
||||
players[i]->DeadLifeState(true);//refactored
|
||||
}
|
||||
//////////////////////////////////////////////////////
|
||||
//-------------card based states effects------------//
|
||||
|
||||
@@ -2665,6 +2665,12 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
|
||||
return NEW AProduceExtraAbility(observer, id, card,s.substr(13));
|
||||
}
|
||||
|
||||
//reducelife to specific value
|
||||
if (s.find("reduceto:") != string::npos)
|
||||
{
|
||||
return NEW AReduceToAbility(observer, id, card,s.substr(9));
|
||||
}
|
||||
|
||||
//flanking
|
||||
if (s.find("flanker") != string::npos)
|
||||
{
|
||||
@@ -4594,6 +4600,8 @@ int ActivatedAbility::isReactingToClick(MTGCardInstance * card, ManaCost * mana)
|
||||
return 0;
|
||||
if (cPhase != MTG_PHASE_FIRSTMAIN && cPhase != MTG_PHASE_SECONDMAIN)
|
||||
return 0;
|
||||
if (player->opponent()->getObserver()->mLayers->stackLayer()->count(0, NOT_RESOLVED) != 0||game->mLayers->stackLayer()->count(0, NOT_RESOLVED) != 0||player->getObserver()->mLayers->stackLayer()->count(0, NOT_RESOLVED) != 0)
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
if (restrictions >= MY_BEFORE_BEGIN && restrictions <= MY_AFTER_EOT)
|
||||
@@ -5016,30 +5024,6 @@ int TriggeredAbility::receiveEvent(WEvent * e)
|
||||
resolve();
|
||||
return 1;
|
||||
}
|
||||
if(dynamic_cast<WEventLife*>(e))
|
||||
{
|
||||
//check life state on life triger
|
||||
WEventLife * lifecheck = dynamic_cast<WEventLife*>(e);
|
||||
if (lifecheck->player->DeadLifeState())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
fireAbility();
|
||||
return 1;
|
||||
}
|
||||
if(dynamic_cast<WEventDamage*>(e))
|
||||
{
|
||||
//check life state on damage trigger
|
||||
WEventDamage * lifecheck = dynamic_cast<WEventDamage*>(e);
|
||||
if (lifecheck->damage->target->type_as_damageable == Damageable::DAMAGEABLE_PLAYER)
|
||||
{
|
||||
Player * triggerPlayer = (Player *) lifecheck->damage->target;
|
||||
if(triggerPlayer->DeadLifeState())
|
||||
return 0;
|
||||
}
|
||||
fireAbility();
|
||||
return 1;
|
||||
}
|
||||
WEventZoneChange * stackCheck = dynamic_cast<WEventZoneChange*>(e);
|
||||
if(stackCheck && (stackCheck->to == game->currentPlayer->game->stack||stackCheck->to == game->currentPlayer->opponent()->game->stack))
|
||||
{
|
||||
|
||||
@@ -739,6 +739,20 @@ int MTGCardInstance::getCurrentToughness()
|
||||
return toughness;
|
||||
}
|
||||
|
||||
//check stack
|
||||
bool MTGCardInstance::StackIsEmptyandSorcerySpeed()
|
||||
{
|
||||
if((getObserver()->mLayers->stackLayer()->count(0, NOT_RESOLVED) == 0) &&
|
||||
(getObserver()->getCurrentGamePhase() == MTG_PHASE_FIRSTMAIN ||
|
||||
getObserver()->getCurrentGamePhase() == MTG_PHASE_SECONDMAIN) &&
|
||||
controller() == getObserver()->currentPlayer &&
|
||||
!getObserver()->isInterrupting)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int MTGCardInstance::canBlock()
|
||||
{
|
||||
if (tapped)
|
||||
|
||||
@@ -310,18 +310,12 @@ int MTGPutInPlayRule::isReactingToClick(MTGCardInstance * card, ManaCost *)
|
||||
{
|
||||
if (game->currentActionPlayer->game->playRestrictions->canPutIntoZone(card, game->currentActionPlayer->game->inPlay) == PlayRestriction::CANT_PLAY)
|
||||
return 0;
|
||||
if (player == currentPlayer
|
||||
&& (game->getCurrentGamePhase() == MTG_PHASE_FIRSTMAIN || game->getCurrentGamePhase() == MTG_PHASE_SECONDMAIN)
|
||||
)
|
||||
{
|
||||
if (card->StackIsEmptyandSorcerySpeed())
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else if ((card->hasType(Subtypes::TYPE_INSTANT)) || card->has(Constants::FLASH)
|
||||
|| (player == card->controller() && !game->isInterrupting
|
||||
&& (game->getCurrentGamePhase() == MTG_PHASE_FIRSTMAIN
|
||||
|| game->getCurrentGamePhase() == MTG_PHASE_SECONDMAIN))
|
||||
)
|
||||
else if ((card->hasType(Subtypes::TYPE_INSTANT)) || card->has(Constants::FLASH) || (card->StackIsEmptyandSorcerySpeed()))
|
||||
{
|
||||
if(card->controller()->epic)
|
||||
return 0;
|
||||
@@ -645,17 +639,12 @@ int MTGAlternativeCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *
|
||||
{
|
||||
if (game->currentActionPlayer->game->playRestrictions->canPutIntoZone(card, game->currentActionPlayer->game->inPlay) == PlayRestriction::CANT_PLAY)
|
||||
return 0;
|
||||
if (player == currentPlayer
|
||||
&& (game->getCurrentGamePhase() == MTG_PHASE_FIRSTMAIN
|
||||
|| game->getCurrentGamePhase() == MTG_PHASE_SECONDMAIN)
|
||||
)
|
||||
if (card->StackIsEmptyandSorcerySpeed())
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else if ((card->hasType(Subtypes::TYPE_INSTANT)) || card->has(Constants::FLASH) || card->has(Constants::SPELLMASTERY) || card->has(Constants::OFFERING)
|
||||
|| (player == card->controller() && !game->isInterrupting
|
||||
&& (game->getCurrentGamePhase() == MTG_PHASE_FIRSTMAIN
|
||||
|| game->getCurrentGamePhase() == MTG_PHASE_SECONDMAIN))
|
||||
)
|
||||
else if ((card->hasType(Subtypes::TYPE_INSTANT)) || card->has(Constants::FLASH) || card->has(Constants::SPELLMASTERY) || card->has(Constants::OFFERING) || (card->StackIsEmptyandSorcerySpeed()))
|
||||
{
|
||||
if(card->controller()->epic)
|
||||
return 0;
|
||||
@@ -1042,11 +1031,7 @@ int MTGMorphCostRule::isReactingToClick(MTGCardInstance * card, ManaCost *)
|
||||
if(card->controller()->epic)//zoetic cavern... morph is casted for a cost...
|
||||
return 0;
|
||||
//note lands can morph too, this is different from other cost types.
|
||||
if ((card->hasType(Subtypes::TYPE_INSTANT)) || card->has(Constants::FLASH) || (player == card->controller()
|
||||
&& !game->isInterrupting
|
||||
&& (game->getCurrentGamePhase() == MTG_PHASE_FIRSTMAIN
|
||||
|| game->getCurrentGamePhase() == MTG_PHASE_SECONDMAIN))
|
||||
)
|
||||
if ((card->hasType(Subtypes::TYPE_INSTANT)) || card->has(Constants::FLASH) || (card->StackIsEmptyandSorcerySpeed()))
|
||||
{
|
||||
if (card->controller()->game->playRestrictions->canPutIntoZone(card, card->controller()->game->stack) == PlayRestriction::CANT_PLAY)
|
||||
return 0;
|
||||
|
||||
@@ -236,7 +236,7 @@ void Player::serumMulligan()
|
||||
//Draw hand no penalty
|
||||
}
|
||||
|
||||
bool Player::DeadLifeState()
|
||||
bool Player::DeadLifeState(bool check)
|
||||
{
|
||||
if ((life <= 0)||(poisonCount >= 10))
|
||||
{
|
||||
@@ -263,7 +263,21 @@ bool Player::DeadLifeState()
|
||||
}
|
||||
if (cantlosers < 1)
|
||||
{
|
||||
getObserver()->setLoser(this);
|
||||
if(!check)
|
||||
{
|
||||
ActionStack * stack = getObserver()->mLayers->stackLayer();
|
||||
for (int i = stack->mObjects.size() - 1; i >= 0; i--)
|
||||
{
|
||||
Interruptible * current = ((Interruptible *) stack->mObjects[i]);
|
||||
Spell * spell = (Spell *) current;
|
||||
if (current->type == ACTION_SPELL)
|
||||
spell->source->controller()->game->putInGraveyard(spell->source);
|
||||
|
||||
current->state = RESOLVED_NOK;
|
||||
}
|
||||
}
|
||||
if(check)
|
||||
game->owner->getObserver()->setLoser(this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user