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:
Anthony Calosa
2015-10-01 22:25:26 +08:00
parent e1c02c8bf5
commit ddee2c08e2
10 changed files with 112 additions and 71 deletions
+3 -1
View File
@@ -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------------//
+8 -24
View File
@@ -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))
{
+14
View File
@@ -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)
+9 -24
View File
@@ -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;
+16 -2
View File
@@ -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;
}
}