storm,cantwin/lose,additionallands,cast restricting

This commit is contained in:
omegablast2002@yahoo.com
2010-09-04 00:16:20 +00:00
parent 3eb8e64a3e
commit c83950a5d4
13 changed files with 356 additions and 17 deletions

View File

@@ -163,7 +163,7 @@ class ActionStack :public GuiLayer{
Player * askIfWishesToInterrupt;
int garbageCollect();
int addAction(Interruptible * interruptible);
Spell * addSpell(MTGCardInstance* card, TargetChooser * tc, ManaCost * mana, int payResult);
Spell * addSpell(MTGCardInstance* card, TargetChooser * tc, ManaCost * mana, int payResult, int storm);
int AddNextGamePhase();
int addPutInGraveyard(MTGCardInstance * card);
int addDraw(Player * player, int nbcards = 1);

View File

@@ -697,6 +697,45 @@ class AADrawer:public ActivatedAbilityTP{
};
//lands, allows to play more land during a turn:
class AAMoreLandPlz:public ActivatedAbilityTP{
public:
WParsedInt *additional;
AAMoreLandPlz(int _id, MTGCardInstance * card,Targetable * _target,ManaCost * _cost, WParsedInt * _additional, int _tap = 0, int who=TargetChooser::UNSET):ActivatedAbilityTP(_id, card,_target,_cost,_tap,who),additional(_additional){
}
int resolve(){
Targetable * _target = getTarget();
Player * player;
if (_target){
if (_target->typeAsTarget() == TARGET_CARD){
player = ((MTGCardInstance *)_target)->controller();
}else{
player = (Player *) _target;
}
player->canPutLandsIntoPlay += additional->getValue();
}
return 1;
}
const char * getMenuText(){
return "Additional Lands";
}
AAMoreLandPlz * clone() const{
AAMoreLandPlz * a = NEW AAMoreLandPlz(*this);
a->additional = NEW WParsedInt(*(a->additional));
a->isClone = 1;
return a;
}
~AAMoreLandPlz(){
SAFE_DELETE(additional);
}
};
/*Gives life to target controller*/
class AALifer:public ActivatedAbilityTP{
public:
@@ -744,7 +783,18 @@ class AAWinGame:public ActivatedAbilityTP{
if (_target->type_as_damageable == DAMAGEABLE_MTGCARDINSTANCE){
_target = ((MTGCardInstance *)_target)->controller();
}
int cantlosers = 0;
MTGGameZone * z = ((Player *)_target)->opponent()->game->inPlay;
int nbcards = z->nb_cards;
for (int i = 0; i < nbcards; ++i){
MTGCardInstance * c = z->cards[i];
if (c->has(Constants::CANTLOSE)){
cantlosers++;
}
}
if(cantlosers < 1){
game->gameOver = ((Player *)_target)->opponent();
}
}
return 1;
}
@@ -4259,6 +4309,93 @@ class AAShuffle:public ActivatedAbilityTP{
}
};
//only 1 spell
class AAOnlyOne:public ActivatedAbilityTP{
public:
AAOnlyOne(int _id, MTGCardInstance * card, Targetable * _target, ManaCost * _cost=NULL, int _tap = 0, int who = TargetChooser::UNSET):ActivatedAbilityTP(_id,card, _target,_cost,_tap,who){
}
int resolve(){
Targetable * _target = getTarget();
Player * player;
if (_target){
if (_target->typeAsTarget() == TARGET_CARD){
player = ((MTGCardInstance *)_target)->controller();
}else{
player = (Player *) _target;
}
player->onlyonecast = 1;
}
return 1;
}
const char * getMenuText(){
return "Only One Spell!";
}
AAOnlyOne * clone() const{
AAOnlyOne * a = NEW AAOnlyOne(*this);
a->isClone = 1;
return a;
}
};
//nospells
class AANoSpells:public ActivatedAbilityTP{
public:
AANoSpells(int _id, MTGCardInstance * card, Targetable * _target, ManaCost * _cost=NULL, int _tap = 0, int who = TargetChooser::UNSET):ActivatedAbilityTP(_id,card, _target,_cost,_tap,who){
}
int resolve(){
Targetable * _target = getTarget();
Player * player;
if (_target){
if (_target->typeAsTarget() == TARGET_CARD){
player = ((MTGCardInstance *)_target)->controller();
}else{
player = (Player *) _target;
}
player->castrestrictedspell = 1;
}
return 1;
}
const char * getMenuText(){
return "No Spells!";
}
AANoSpells * clone() const{
AANoSpells * a = NEW AANoSpells(*this);
a->isClone = 1;
return a;
}
};
//NoCreature
class AANoCreatures:public ActivatedAbilityTP{
public:
AANoCreatures(int _id, MTGCardInstance * card, Targetable * _target, ManaCost * _cost=NULL, int _tap = 0, int who = TargetChooser::UNSET):ActivatedAbilityTP(_id,card, _target,_cost,_tap,who){
}
int resolve(){
Targetable * _target = getTarget();
Player * player;
if (_target){
if (_target->typeAsTarget() == TARGET_CARD){
player = ((MTGCardInstance *)_target)->controller();
}else{
player = (Player *) _target;
}
player->castrestrictedcreature = 1;
}
return 1;
}
const char * getMenuText(){
return "No Creatures!";
}
AANoCreatures * clone() const{
AANoCreatures * a = NEW AANoCreatures(*this);
a->isClone = 1;
return a;
}
};
//Random Discard
class AARandomDiscarder:public ActivatedAbilityTP{
public:

View File

@@ -114,8 +114,18 @@ class Constants
ABSORB = 56,//this need to be coded for players too "If a source would deal damage"
TREASON = 57,
UNEARTH = 58,
CANTLOSE = 59,
CANTLIFELOSE = 60,
CANTMILLLOSE = 61,
CANTCASTCREATURE = 62,
CANTCAST = 63,
CANTCASTINSTANTSORCERY = 64,
STORM = 65,
BOTHCANTCAST = 66,
BOTHNOCREATURE = 67,
BOTHONESPELL = 68,
NB_BASIC_ABILITIES = 59,
NB_BASIC_ABILITIES = 69,
RARITY_S = 'S', //Special Rarity

View File

@@ -158,7 +158,7 @@ class MTGPlayerCards {
void drawFromLibrary();
void showHand();
void resetLibrary();
void initDeck(MTGDeck * deck);
void initDeck(MTGDeck * deck);
MTGCardInstance * putInGraveyard(MTGCardInstance * card);
MTGCardInstance * putInExile(MTGCardInstance * card);
MTGCardInstance * putInHand(MTGCardInstance * card);

View File

@@ -22,6 +22,13 @@ class Player: public Damageable{
JTexture * mAvatarTex;
JQuad * mAvatar;
int canPutLandsIntoPlay;
int castedspellsthisturn;
int onlyonecast;
int castrestrictedcreature;
int castrestrictedspell;
int cantcastspell;
int cantcastcreature;
int cantcastinso;
MTGPlayerCards * game;
int afterDamage();
int poisoned();

View File

@@ -621,6 +621,11 @@ MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * pMana, const char * ty
cd.setType(type);
card = NULL;
while((card = cd.nextmatch(game->hand, card))){
if (card->hasType(Subtypes::TYPE_CREATURE) && this->castrestrictedcreature < 0 && this->castrestrictedspell < 0) continue;
if (card->hasType(Subtypes::TYPE_ENCHANTMENT) && this->castrestrictedspell < 0) continue;
if (card->hasType(Subtypes::TYPE_ARTIFACT) && this->castrestrictedspell < 0) continue;
if (card->hasType(Subtypes::TYPE_SORCERY) && this->castrestrictedspell < 0) continue;
if (card->hasType(Subtypes::TYPE_INSTANT) && this->castrestrictedspell < 0) continue;
if (card->hasType(Subtypes::TYPE_LAND) && !this->canPutLandsIntoPlay) continue;
if (card->hasType(Subtypes::TYPE_LEGENDARY) && game->inPlay->findByName(card->name)) continue;
int currentCost = card->getManaCost()->getConvertedCost();
@@ -709,12 +714,20 @@ int AIPlayerBaka::computeActions(){
nextCardToPlay = FindCardToPlay(currentMana, "land");
//look for the most expensive creature we can afford
if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(currentMana, "creature");
if(castrestrictedspell == 0 && cantcastspell == 0){
if(onlyonecast == 0 || castedspellsthisturn < onlyonecast){
if(castrestrictedcreature == 0 && cantcastcreature == 0){
if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(currentMana, "creature");
}
//Let's Try an enchantment maybe ?
if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(currentMana, "enchantment");
if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(currentMana, "artifact");
if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(currentMana, "sorcery");
if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(currentMana, "instant");
if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(currentMana, "enchantment");
if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(currentMana, "artifact");
if (cantcastinso == 0){
if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(currentMana, "sorcery");
if (!nextCardToPlay) nextCardToPlay = FindCardToPlay(currentMana, "instant");
}
}
}
if (potential) delete(currentMana);
if (nextCardToPlay){
if (potential){

View File

@@ -389,12 +389,13 @@ int ActionStack::addAction(Interruptible * action){
return 1;
}
Spell * ActionStack::addSpell(MTGCardInstance * _source, TargetChooser * tc, ManaCost * mana, int payResult){
Spell * ActionStack::addSpell(MTGCardInstance * _source, TargetChooser * tc, ManaCost * mana, int payResult,int storm){
#if defined (WIN32) || defined (LINUX)
char buf[4096], *p = buf;
sprintf(buf, "ACTIONSTACK Add spell\n");
OutputDebugString(buf);
#endif
if(storm > 0){ mana = NULL;}
Spell * spell = NEW Spell(mCount,_source,tc, mana,payResult);
addAction(spell);
if (!game->players[0]->isAI() &&

View File

@@ -97,6 +97,13 @@ void GameObserver::nextGamePhase(){
if (currentGamePhase == Constants::MTG_PHASE_BEFORE_BEGIN){
cleanupPhase();
currentPlayer->canPutLandsIntoPlay = 1;
currentPlayer->castedspellsthisturn = 0;
currentPlayer->castrestrictedcreature = 0;
currentPlayer->castrestrictedspell = 0;
currentPlayer->cantcastcreature = 0;
currentPlayer->cantcastspell = 0;
currentPlayer->cantcastinso = 0;
currentPlayer->onlyonecast = 0;
currentPlayer->damageCount = 0;
currentPlayer->preventable = 0;
mLayers->actionLayer()->cleanGarbage(); //clean abilities history for this turn;
@@ -318,7 +325,21 @@ void GameObserver::stateEffects()
}
}
for (int i =0; i < 2; i++)
if (players[i]->life <= 0) gameOver = players[i];
if (players[i]->life <= 0){
int cantlosers = 0;
MTGGameZone * z = players[i]->game->inPlay;
int nbcards = z->nb_cards;
for (int j = 0; j < nbcards; ++j){
MTGCardInstance * c = z->cards[j];
if (c->has(Constants::CANTLOSE) || c->has(Constants::CANTLIFELOSE)){
cantlosers++;
}
}
if(cantlosers < 1){
gameOver = players[i];
}
}
for (int i =0; i < 2; i++)
if (players[i]->poisonCount >= 10) gameOver = players[i];
}

View File

@@ -906,6 +906,24 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
a->oneShot = 1;
return a;
}
//additional lands per turn
found = s.find("land:");
if (found != string::npos){
size_t start = s.find(":",found);
size_t end = s.find(" ",start);
string additionalStr;
if (end != string::npos){
additionalStr = s.substr(start+1,end-start-1);
}else{
additionalStr = s.substr(start+1);
}
WParsedInt * additional = NEW WParsedInt(additionalStr,spell,card);
Targetable * t = NULL;
if (spell) t = spell->getNextTarget();
MTGAbility * a = NEW AAMoreLandPlz(id,card,t,NULL,additional,0,who);
a->oneShot = 1;
return a;
}
//Deplete
found = s.find("deplete:");
@@ -935,6 +953,35 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
a->oneShot = 1;
return a;
}
//cantcastspells
found = s.find("onlyonespell");
if (found != string::npos){
Targetable * t = NULL;
if (spell) t = spell->getNextTarget();
MTGAbility * a = NEW AAOnlyOne(id,card,t,NULL,0,who);
a->oneShot = 1;
return a;
}
//cantcastspells
found = s.find("nospells");
if (found != string::npos){
Targetable * t = NULL;
if (spell) t = spell->getNextTarget();
MTGAbility * a = NEW AANoSpells(id,card,t,NULL,0,who);
a->oneShot = 1;
return a;
}
//cantcastcreature
found = s.find("nocreatures");
if (found != string::npos){
Targetable * t = NULL;
if (spell) t = spell->getNextTarget();
MTGAbility * a = NEW AANoCreatures(id,card,t,NULL,0,who);
a->oneShot = 1;
return a;
}
//Discard
found = s.find("discard:");

View File

@@ -67,6 +67,16 @@ const char* Constants::MTGBasicAbilities[] = {
"absorb",//timeshifted sliver ability. if damage would be dealt to card, prevent 1 of that damage.
"treason",
"unearth",
"cantlose",
"cantlifelose",
"cantmilllose",
"cantcastcreature",
"cantspellcast",
"cantcastinstantsorcery",
"storm",
"bothcantcast",
"bothnocreature",
"bothonecast",
};

View File

@@ -79,7 +79,17 @@ void MTGPlayerCards::initGame(int shuffle, int draw){
void MTGPlayerCards::drawFromLibrary(){
if (!library->nb_cards) {
GameObserver::GetInstance()->gameOver = library->owner;
int cantlosers = 0;
MTGGameZone * z = library->owner->game->inPlay;
int nbcards = z->nb_cards;
for (int i = 0; i < nbcards; ++i){
MTGCardInstance * c = z->cards[i];
if (c->has(Constants::CANTLOSE) || c->has(Constants::CANTMILLLOSE)){
cantlosers++;
}
}
if(cantlosers < 1){
GameObserver::GetInstance()->gameOver = library->owner;}
return;
}
MTGCardInstance * toMove = library->cards[library->nb_cards-1];

View File

@@ -32,18 +32,81 @@ int cardsinhand = game->players[0]->game->hand->nb_cards;
ManaCost * playerMana = player->getManaPool();
ManaCost * cost = card->getManaCost();
ManaCost * alternative = card->getManaCost()->alternative;
#ifdef WIN32
cost->Dump();
#endif
//cantcast restrictions---------
int cantcreaturecasters = 0;
MTGGameZone * z = card->controller()->game->inPlay;
int nbcards = z->nb_cards;
for (int j = 0; j < nbcards; ++j){
MTGCardInstance * c = z->cards[j];
if (c->has(Constants::CANTCASTCREATURE)){
player->cantcastcreature = 1;
cantcreaturecasters++;
}
}
int cantcasters = 0;
for (int j = 0; j < nbcards; ++j){
MTGCardInstance * c = z->cards[j];
if (c->has(Constants::CANTCAST)){
player->cantcastspell = 1;
cantcasters++;
}
}
int cantinsocasters = 0;
for (int j = 0; j < nbcards; ++j){
MTGCardInstance * c = z->cards[j];
if (c->has(Constants::CANTCASTINSTANTSORCERY)){
player->cantcastinso = 1;
cantinsocasters++;
}
}
//restrict both players-------
for (int j = 0; j < nbcards; ++j){
MTGCardInstance * c = z->cards[j];
if (c->has(Constants::BOTHCANTCAST)){
player->cantcastspell = 1;
player->opponent()->cantcastspell = 1;
}
}
for (int j = 0; j < nbcards; ++j){
MTGCardInstance * c = z->cards[j];
if (c->has(Constants::BOTHNOCREATURE)){
player->cantcastcreature = 1;
player->opponent()->cantcastcreature = 1;
}
}
for (int j = 0; j < nbcards; ++j){
MTGCardInstance * c = z->cards[j];
if (c->has(Constants::BOTHONESPELL)){
player->onlyonecast = 1;
player->opponent()->onlyonecast = 1;
}
}
if(player->castedspellsthisturn > 0 && player->onlyonecast > 0){return 0;}
if(player->castrestrictedspell > 0){return 0;}
if(player->castrestrictedcreature > 0 && card->hasType("creature")){return 0;}
if(cantcasters > 0 && !card->hasType("land")){ return 0;}
if(cantinsocasters > 0 && card->hasType("sorcery")){ return 0;}
if(cantinsocasters > 0 && card->hasType("instant")){ return 0;}
if(cantcreaturecasters > 0 && card->hasType("creature")){ return 0;}//---this ends the cant cast restriction.
//cost of card.
if(alternative && playerMana->canAfford(alternative)){
return 1;
}
if (playerMana->canAfford(cost)){
return 1;
return 1;//play if you can afford too.
}
}
return 0;
return 0;//dont play if you cant afford it.
}
int MTGPutInPlayRule::reactToClick(MTGCardInstance * card){
if (!isReactingToClick(card)) return 0;
@@ -101,13 +164,26 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card){
Spell * spell = NULL;
MTGCardInstance * copy = player->game->putInZone(card, player->game->hand, player->game->stack);
if (game->targetChooser){
spell = game->mLayers->stackLayer()->addSpell(copy,game->targetChooser, spellCost,payResult);
spell = game->mLayers->stackLayer()->addSpell(copy,game->targetChooser, spellCost,payResult,0);
game->targetChooser = NULL;
player->castedspellsthisturn += 1;
}else{
spell = game->mLayers->stackLayer()->addSpell(copy,NULL, spellCost, payResult);
}
copy->X = spell->computeX(copy);
spell = game->mLayers->stackLayer()->addSpell(copy,NULL, spellCost, payResult,0);
player->castedspellsthisturn += 1;
}
if(card->has(Constants::STORM)){
int storm = player->castedspellsthisturn;
ManaCost * spellCost = player->getManaPool();
for(int i = storm; i > 1; i--){
spell = game->mLayers->stackLayer()->addSpell(copy,NULL, spellCost, payResult,1);
}
}//end of storm
if(!card->has(Constants::STORM)){
copy->X = spell->computeX(copy);
}
}
return 1;
}

View File

@@ -12,6 +12,13 @@ Player::Player(MTGPlayerCards * deck, string file, string fileSmall) : Damageabl
game->setOwner(this);
manaPool = NEW ManaPool(this);
canPutLandsIntoPlay = 1;
castedspellsthisturn = 0;
castrestrictedspell = 0;
castrestrictedcreature = 0;
cantcastcreature = 0;
cantcastspell = 0;
cantcastinso = 0;
onlyonecast = 0;
poisonCount = 0;
damageCount = 0;
preventable = 0;