fix windswept_heath.txt missing choice 1, added unearth support without workaround, tweaked alternative cost, added treason/sneak attack ability, added frozen.

This commit is contained in:
omegablast2002@yahoo.com
2010-09-01 21:31:27 +00:00
parent 17eef3ef6f
commit 45f37b7545
13 changed files with 177 additions and 33 deletions

View File

@@ -11,6 +11,7 @@ library:Forest,Plains,Mountain,Swamp,Island
[PLAYER2]
[DO]
Windswept Heath
choice 1
Plains
[ASSERT]
firstmain

View File

@@ -53,8 +53,6 @@ public:
intValue = target->getManaCost()->getConvertedCost();
}else if (s == "lifetotal"){
intValue = target->controller()->life;
}else if (s == "sunburst"){
intValue = target->costAmount;
}else if (s == "odcount"){
intValue = target->controller()->opponent()->damageCount;
}else if (s == "opponentlifetotal"){
@@ -2330,6 +2328,32 @@ class AAUntapper:public ActivatedAbility{
}
};
/* Can prevent a card from untapping next untap */
class AAFrozen:public ActivatedAbility{
public:
AAFrozen(int id, MTGCardInstance * card, MTGCardInstance * _target,ManaCost * _cost = NULL, int doTap = 0):ActivatedAbility(id,card, _cost,0,doTap){
target = _target;
}
int resolve(){
MTGCardInstance * _target = (MTGCardInstance *) target;
if (_target){
while (_target->next) _target=_target->next; //This is for cards such as rampant growth
_target->frozen += 1;
}
return 1;
}
const char * getMenuText(){
return "Freeze";
}
AAFrozen * clone() const{
AAFrozen * a = NEW AAFrozen(*this);
a->isClone = 1;
return a;
}
};
// Add life of gives damage if a given zone has more or less than [condition] cards at the beginning of [phase]
//Ex : the rack, ivory tower...

View File

@@ -44,11 +44,10 @@ class MTGCardInstance: public CardPrimitive, public MTGCard, public Damageable {
MTGGameZone * currentZone;
Pos* view;
int X;
int costAmount;
int frozen;
int regenerateTokens;
int isToken;
int stillInUse();
int getCostAmount();
Player * lastController;
MTGGameZone * getCurrentZone();
MTGGameZone * previousZone;
@@ -75,7 +74,7 @@ class MTGCardInstance: public CardPrimitive, public MTGCard, public Damageable {
int removeType(int value, int removeAll = 0);
//Combat
bool blocked; //Blocked this turn or not?
bool blocked; //Blocked this turn or not?
MTGCardInstance * defenser;
list<MTGCardInstance *>blockers;
int attacker;

View File

@@ -111,8 +111,11 @@ class Constants
WILTING = 53,
VIGOR = 54,
CHANGELING = 55,
ABSORB = 56,//this need to be coded for players too "If a source would deal damage"
TREASON = 57,
UNEARTH = 58,
NB_BASIC_ABILITIES = 56,
NB_BASIC_ABILITIES = 59,
RARITY_S = 'S', //Special Rarity

View File

@@ -64,6 +64,23 @@ class MTGPersistRule:public MTGAbility{
virtual MTGPersistRule * clone() const;
};
class MTGUnearthRule:public MTGAbility{
public:
MTGUnearthRule(int _id);
int receiveEvent(WEvent * event);
virtual ostream& toString(ostream& out) const;
int testDestroy();
virtual MTGUnearthRule * clone() const;
};
class MTGSneakAttackRule:public MTGAbility{
public:
MTGSneakAttackRule(int _id);
int receiveEvent(WEvent * event);
virtual ostream& toString(ostream& out) const;
int testDestroy();
virtual MTGSneakAttackRule * clone() const;
};
class MTGTokensCleanup:public MTGAbility{
public:
@@ -146,7 +163,6 @@ class MTGDeathtouchRule:public MTGAbility{
virtual MTGDeathtouchRule * clone() const;
};
/* HUD Display */
class HUDString {

View File

@@ -45,6 +45,10 @@ int Damage::resolve(){
target = ev->damage->target;
if (!damage) return 0;
//asorbing effects for cards controller-----------
//reserved for culmulitive absorb ability coding
//prevent next damage-----------------------------
if((target)->preventable >= 1) {
int preventing =(target)->preventable;
@@ -71,6 +75,9 @@ int Damage::resolve(){
damage = 0;
(_target)->counters->removeCounter(1,1);
}
if ((_target)->has(Constants::ABSORB)) {
damage -= 1;
}
if ((_target)->has(Constants::WILTING)) {
for (int i = 0; i < damage; i++){
for (int i = damage; i > 0; i--){

View File

@@ -25,6 +25,8 @@ void DuelLayers::init(){
action->Add(NEW MTGBlockRule(-1));
action->Add(NEW MTGLegendRule(-1));
action->Add(NEW MTGPersistRule(-1));
action->Add(NEW MTGUnearthRule(-1));
action->Add(NEW MTGSneakAttackRule(-1));
action->Add(NEW MTGLifelinkRule(-1));
action->Add(NEW MTGDeathtouchRule(-1));
action->Add(NEW OtherAbilitiesEventReceiver(-1));

View File

@@ -114,7 +114,21 @@ void GameObserver::nextGamePhase(){
for (int i = 0; i < 2; ++i)
players[i]->getManaPool()->init();
//After End of turn
// //End of turn--unearth clean up---leaving this as comment for code refference. origanal method i had for unearth now handled by sneakattackrule.
//if (currentGamePhase == Constants::MTG_PHASE_ENDOFTURN) {
// GameObserver *game = game->GetInstance();
// Player * p = game->currentPlayer;
// MTGGameZone * z = p->game->inPlay;
// for (int i= 0; i < z->nb_cards; i++){
// MTGCardInstance * card = z->cards[i];
//if (card->has(Constants::UNEARTH)) {
// for(i = z->nb_cards; i > -1; i--){
// card->controller()->game->putInExile(card);
//}
// }
// }
//}
if (currentGamePhase == Constants::MTG_PHASE_AFTER_EOT){
//Auto Hand cleaning, in case the player didn't do it himself
while(currentPlayer->game->hand->nb_cards > 7)
@@ -465,12 +479,11 @@ int GameObserver::untap(MTGCardInstance * card) {
return 0;
}
if (card->has(Constants::DOESNOTUNTAP)) return 0;
if (card->frozen > 0) return 0;
card->attemptUntap();
return 1;
}
TargetChooser * GameObserver::getCurrentTargetChooser(){
TargetChooser * _tc = mLayers->actionLayer()->getCurrentTargetChooser();
if (_tc) return _tc;

View File

@@ -1193,6 +1193,14 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG
}
}
//frozen, next untap this does not untap.
found = s.find("frozen");
if (found != string::npos){
MTGAbility * a = NEW AAFrozen(id,card,target);
a->oneShot = 1;
return a;
}
//Untapper (Ley Druid...)
found = s.find("untap");
if (found != string::npos){

View File

@@ -97,6 +97,7 @@ void MTGCardInstance::initMTGCI(){
belongs_to=NULL;
tapped = 0;
untapping = 0;
frozen = 0;
summoningSickness = 1;
preventable = 0;
target = NULL;
@@ -109,7 +110,6 @@ void MTGCardInstance::initMTGCI(){
next = NULL;
lastController = NULL;
regenerateTokens = 0;
costAmount = 0;
blocked = false;
currentZone = NULL;
data = this; //an MTGCardInstance point to itself for data, allows to update it without killing the underlying database item
@@ -297,10 +297,6 @@ int MTGCardInstance::hasSummoningSickness(){
return 1;
}
int MTGCardInstance::getCostAmount(){
return 1;
}
MTGCardInstance * MTGCardInstance::changeController(Player * newController){
Player * originalOwner = controller();
if (originalOwner == newController) return this;

View File

@@ -64,6 +64,9 @@ const char* Constants::MTGBasicAbilities[] = {
"wilting",//source takes damage in the form of -1/-1 counters.
"vigor",//instead of taking damage the source gains +1/+1 counters
"changeling",//this card is every creature type at all times
"absorb",//timeshifted sliver ability. if damage would be dealt to card, prevent 1 of that damage.
"treason",
"unearth",
};

View File

@@ -355,9 +355,11 @@ void MTGInPlay::untapAll(){
for (i = 0; i < nb_cards; i ++){
MTGCardInstance * card = cards[i];
card->setUntapping();
if (!card->basicAbilities[Constants::DOESNOTUNTAP]){
card->attemptUntap();
}
if (!card->basicAbilities[Constants::DOESNOTUNTAP]){
if(card->frozen < 1) {card->attemptUntap();}
if(card->frozen >= 1) {card->frozen = 0;}
}
}
}

View File

@@ -40,9 +40,8 @@ int cardsinhand = game->players[0]->game->hand->nb_cards;
return 1;
}
if (playerMana->canAfford(cost)){
return 1;
}
return 1;
}
}
return 0;
}
@@ -53,19 +52,10 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card){
ManaCost * alternative = card->getManaCost()->alternative;
ManaCost * playerMana = player->getManaPool();
//this handles extra cost payments at the moment a card is played.
if (cost->isExtraPaymentSet()){
if (!game->targetListIsSet(card)){
return 0;
}
}else{
cost->setExtraCostsAction(this, card);
game->waitForExtraPayment = cost->extraCosts;
return 0;
}
//as long as you dont have enough mana to pay the real cost, and the alternative contains extra cost, add extras
if(!playerMana->canAfford(cost) && playerMana->canAfford(alternative)){
if (cost->alternative->isExtraPaymentSet()){
if (cost->alternative->isExtraPaymentSet()){
if (!game->targetListIsSet(card)){
return 0;
}
@@ -76,6 +66,15 @@ int MTGPutInPlayRule::reactToClick(MTGCardInstance * card){
}
}
//------------------------------------------------------------------------
if (cost->isExtraPaymentSet()){
if (!game->targetListIsSet(card)){
return 0;
}
}else{
cost->setExtraCostsAction(this, card);
game->waitForExtraPayment = cost->extraCosts;
return 0;
}
ManaCost * previousManaPool = NEW ManaCost(player->getManaPool());
int payResult = player->getManaPool()->pay(card->getManaCost());
@@ -550,8 +549,80 @@ HUDDisplay::~HUDDisplay(){
a->isClone = 1;
return a;
}
//unearth rule----------------------------------
//if the card leaves play, exile it instead.
MTGUnearthRule::MTGUnearthRule(int _id):MTGAbility(_id,NULL){};
int MTGUnearthRule::receiveEvent(WEvent * event){
if (event->type == WEvent::CHANGE_ZONE){
WEventZoneChange * e = (WEventZoneChange *) event;
MTGCardInstance * card = e->card->previous;
if (card && card->basicAbilities[Constants::UNEARTH]){
int ok = 0;
for (int i = 0; i < 2 ; i++){
Player * p = game->players[i];
if (e->from == p->game->inPlay) ok = 1;
}
if (!ok) return 0;
for (int i = 0; i < 2 ; i++){
Player * p = game->players[i];
if (e->to == p->game->graveyard || e->to == p->game->hand || e->to == p->game->library){
p->game->putInExile(e->card);
return 1;
}
}
}
}
return 0;
}
ostream& MTGUnearthRule::toString(ostream& out) const
{
out << "MTGUnearthRule ::: (";
return MTGAbility::toString(out) << ")";
}
int MTGUnearthRule::testDestroy(){return 0;}
MTGUnearthRule * MTGUnearthRule::clone() const{
MTGUnearthRule * a = NEW MTGUnearthRule(*this);
a->isClone = 1;
return a;
}
//----------------------------------------------------------------------
//sneakattack rule------------------------------------------------------
//this rule also handles the exile of unearth cards at end of turn.
MTGSneakAttackRule::MTGSneakAttackRule(int _id):MTGAbility(_id,NULL){};
int MTGSneakAttackRule::receiveEvent(WEvent *e){
if (WEventPhaseChange* event = dynamic_cast<WEventPhaseChange*>(e)) {
if (Constants::MTG_PHASE_ENDOFTURN == event->from->id) {
for (int j = 0; j < 2 ; j++){
Player * p = game->players[j];
MTGGameZone * z = p->game->inPlay;
for (int i= 0; i < z->nb_cards; i++){
MTGCardInstance * card = z->cards[i];
if (card->has(Constants::TREASON)) {p->game->putInGraveyard(card);i--;}
if (card->has(Constants::UNEARTH)) {p->game->putInExile(card);i--;}
}
}
}
return 1;
}
return 1;
}
ostream& MTGSneakAttackRule::toString(ostream& out) const
{
out << "MTGSneakAttackRule ::: (";
return MTGAbility::toString(out) << ")";
}
int MTGSneakAttackRule::testDestroy(){return 0;}
MTGSneakAttackRule * MTGSneakAttackRule::clone() const{
MTGSneakAttackRule * a = NEW MTGSneakAttackRule(*this);
a->isClone = 1;
return a;
}
//-------------------------------------------------------------------
MTGTokensCleanup::MTGTokensCleanup(int _id):MTGAbility(_id, NULL){}
int MTGTokensCleanup::receiveEvent(WEvent * e){
@@ -684,4 +755,3 @@ HUDDisplay::~HUDDisplay(){
a->isClone = 1;
return a;
}