Page 1 of 1

Global Ruin

PostPosted: 20 Sep 2008, 21:46
by jpb
DennisBergkamp suggested that this card be added. Currently the computer cannot play it. This card was very tricky to get working and took a few hours. One tough spot was to make sure all of the variables got reset if a user canceled playing the spell. This needs to be done with some cards so the next time they play the spell things aren't in a bad state. Quite a of the problems we see in MTG forge are due to cards not cleaning up correctly. I did not test this card in many scenarios, but I tried a few. Let me know how it works for you.

Add this to cards.txt

Code: Select all
Global Ruin
4 W
Sorcery
Each player chooses from the lands he or she controls a land of each basic land type and sacrifices the rest.
Add this to CardFactory.java
Code: Select all
        //*************** START *********** START **************************
       else if(cardName.equals("Global Ruin"))
       {
         final CardList target = new CardList();
         //need to use arrays so we can declare them final and still set the values in the input and runtime classes. This is a hack.
         final int[] index = new int[1];
         final int[] countBase = new int[1];
         final Vector humanBasic = new Vector();

         final SpellAbility spell = new Spell(card)
         {
           public boolean canPlayAI()
           {
             return false;
             //should check if computer has land in hand, or if computer has more basic land types than human.
           }
           public void resolve()
           {
             //add computer's lands to target
             int computerCountBase = 0;
             Vector computerBasic = new Vector();
            
           //figure out which basic land types the computer has
           CardList land = new CardList(AllZone.Computer_Play.getCards());
           String basic[] = {"Forest", "Plains", "Mountain", "Island", "Swamp"};
            
           for (int i = 0; i < basic.length; i++)
           {
             CardList cl = land.getType(basic[i]);
             if (!cl.isEmpty())
             {
               //remove one land of this basic type from this list
               //the computer AI should really jump in here and select the land which is the best.
               //to determine the best look at which lands have enchantments, which lands are tapped
               cl.remove(cl.get(0));
               //add the rest of the lands of this basic type to the target list, this is the list which will be sacrificed.
               target.addAll(cl.toArray());
             }
           }
              
             //when this spell resolves all basic lands which were not selected are sacrificed.
             for(int i = 0; i < target.size(); i++)
               if(AllZone.GameAction.isCardInPlay(target.get(i)))
                 AllZone.GameAction.sacrifice(target.get(i));
           }//resolve()
         };//SpellAbility


         final Input input = new Input()
         {
          private int count;
           public void showMessage()
           { //count is the current index we are on.
             //countBase[0] is the total number of basic land types the human has
             //index[0] is the number to offset the index by
             count = countBase[0] - index[0] - 1; //subtract by one since humanBasic is 0 indexed.
             if(count<0){
                //need to reset the variables in case they cancel this spell and it stays in hand.
                humanBasic.clear();
                countBase[0] = 0;
                index[0] = 0;
                stop();
             }
             else{
                AllZone.Display.showMessage("Select target " + humanBasic.get(count) +" land to not sacrifice");
                ButtonUtil.enableOnlyCancel();
             }
           }
           public void selectButtonCancel() {stop();}
           public void selectCard(Card c, PlayerZone zone)
           {
             if(c.isLand() && zone.is(Constant.Zone.Play) && c.getController().equals(Constant.Player.Human) && c.getName().equals(humanBasic.get(count)))
             {
               //get all other basic[count] lands human player controls and add them to target
              PlayerZone humanPlay = AllZone.getZone(Constant.Zone.Play, Constant.Player.Human);
               CardList land = new CardList(humanPlay.getCards());
               CardList cl = land.getType((String)humanBasic.get(count));
               cl.remove(c);
               target.addAll(cl.toArray());
              
               index[0]++;
               showMessage();

               if(index[0] >= humanBasic.size())
                 stopSetNext(new Input_PayManaCost(spell));
             }
           }//selectCard()
         };//Input

         Input runtime = new Input()
         {
           public void showMessage()
           {
             countBase[0] = 0;
            //figure out which basic land types the human has
            //put those in an set to use later
            CardList land = new CardList(AllZone.Human_Play.getCards());
            String basic[] = {"Forest", "Plains", "Mountain", "Island", "Swamp"};
         
            for (int i = 0; i < basic.length; i++)
            {
              CardList c = land.getType(basic[i]);
              if (!c.isEmpty())
              {
                humanBasic.add(basic[i]);
                countBase[0]++;
              }
            }
            if(countBase[0] == 0){
               //human has no basic land, so don't prompt to select one.
               stop();
            }
            else{
               index[0] = 0;
               target.clear();
               stopSetNext(input);
            }
           }
         };//Input

         card.clearSpellAbility();
         card.addSpellAbility(spell);
         spell.setBeforePayMana(runtime);
       }//*************** END ************ END **************************
You will need to dig up the url for the card image if you want it.

I would be really interested in the cases where the human does not have any basic land types (use moxes or creatures to create the mana). I wonder if the code for this spell would still work then. Please let me know anything you test with this card.

Re: Global Ruin

PostPosted: 21 Sep 2008, 04:34
by DennisBergkamp
Whoa, I just noticed this! Thanks a lot, great job :D
Very tricky code indeed, I don't understand half of it.

Re: Global Ruin

PostPosted: 23 Sep 2008, 13:26
by mtgrares
Complicated cards indeed, I'll added it.