It is currently 29 Oct 2025, 05:57
   
Text Size

Code from Beached As

Post MTG Forge Related Programming Questions Here

Moderators: timmermac, Agetian, friarsol, Blacksmith, KrazyTheFox, CCGHQ Admins

Re: Code from Beached As

Postby Rob Cashwalker » 01 May 2010, 11:50

Somewhere, the stack object calls to the resolve method of any spell or ability on the stack. (Search for ".resolve")
It would be there, that a check should be made to see if the item being resolved is a Spell or an Ability. How, I'm not too sure, since they're derived from the same classes.... But that would be the proper location to increment a storm count.
The Force will be with you, Always.
User avatar
Rob Cashwalker
Programmer
 
Posts: 2167
Joined: 09 Sep 2008, 15:09
Location: New York
Has thanked: 5 times
Been thanked: 40 times

Re: Code from Beached As

Postby Beached As » 01 May 2010, 14:42

I think i got it. I went into some dangerous territory though so people should definitely test this but i've got Empty the Warrens (and thus hopefully most of the storm cards) to work. However; right now, its still resolving the storm spell as one spell. Because i made quite a few changes in MagicStack.java and Phase.java, i'm gonna attach the code for the whole file. Search "// Beached As" to find where i changed the code. If you guys approve of this code then i'll start adding other storm cards

MagicStack.java

Code: Select all
package forge;
import java.util.*;

public class MagicStack extends MyObservable
{
  private ArrayList<SpellAbility> stack = new ArrayList<SpellAbility>();
  // Beached As Start
  private ArrayList<SpellAbility> SpellStack = new ArrayList<SpellAbility>();
private Object StormCount;
static int      StackMax;
static int      StackCurrent;
 // Beached As End
  public void reset()
  {
     stack.clear();
     this.updateObservers();
  }
 
  public void add(SpellAbility sp, boolean useX)
  {
     if (!useX)
        this.add(sp);
     else
     {
        if(sp instanceof Ability_Mana || sp instanceof Ability_Triggered)//TODO make working triggered abilities!
           sp.resolve();
        else
           push(sp);
     }
  }

  public void add(SpellAbility sp)
  {
     if(sp instanceof Ability_Mana || sp instanceof Ability_Triggered)//TODO make working triggered abilities!
        sp.resolve();
     else {
        if (!sp.isMultiKicker() && !sp.isXCost())
        {
           push(sp);
        }
        else if (sp.isXCost())
        {
           final SpellAbility sa = sp;
           final Ability ability = new Ability(sp.getSourceCard(), sa.getXManaCost())
           {
              public void resolve()
              {
                 Card crd = this.getSourceCard();
                 crd.addXManaCostPaid(1);
              }
           };
          
           final Command unpaidCommand = new Command()
           {
            private static final long serialVersionUID = -3342222770086269767L;

            public void execute()
            {
                 push(sa);
            }
           };
          
           final Command paidCommand = new Command() {
            private static final long serialVersionUID = -2224875229611007788L;

            public void execute() {
                       ability.resolve();
                       Card crd = sa.getSourceCard();
                       AllZone.InputControl.setInput(new Input_PayManaCost_Ability("Pay X cost for " + crd.getName() + " (X=" +crd.getXManaCostPaid()+")\r\n",
                              ability.getManaCost(), this, unpaidCommand, true));
            }
             };
          
           if(sp.getSourceCard().getController().equals(Constant.Player.Human)) {
                   AllZone.InputControl.setInput(new Input_PayManaCost_Ability("Pay X cost for " + sp.getSourceCard().getName() + " (X=0)\r\n",
                           ability.getManaCost(), paidCommand, unpaidCommand, true));
             }
           else //computer
             {
              int neededDamage = CardFactoryUtil.getNeededXDamage(sa);
                
              while(ComputerUtil.canPayCost(ability) && neededDamage != sa.getSourceCard().getXManaCostPaid())
              {
                 ComputerUtil.playNoStack(ability);
              }
              push(sa);
             }
        }
        else if (sp.isMultiKicker()) //both X and multi is not supported yet
        {   
           final SpellAbility sa = sp;
           final Ability ability = new Ability(sp.getSourceCard(), sp.getMultiKickerManaCost())
           {
              public void resolve()
              {
                 this.getSourceCard().addMultiKickerMagnitude(1);
                 //System.out.println("MultiKicker has been paid (currently multi-kicked " + this.getSourceCard().getName() + " " + this.getSourceCard().getMultiKickerMagnitude()+ " times)");
              }
           };
          
           final Command unpaidCommand = new Command()
           {
            private static final long serialVersionUID = -3342222770086269767L;

            public void execute()
              {
                 push(sa);
              }
           };
          
           final Command paidCommand = new Command() {
                private static final long serialVersionUID = -6037161763374971106L;
               public void execute() {
                       ability.resolve();
                       AllZone.InputControl.setInput(new Input_PayManaCost_Ability("Multikicker for " + sa.getSourceCard() + "\r\n",
                              ability.getManaCost(), this, unpaidCommand));
                   }
             };
          
           if(sp.getSourceCard().getController().equals(Constant.Player.Human)) {
                   AllZone.InputControl.setInput(new Input_PayManaCost_Ability("Multikicker for " + sp.getSourceCard() + "\r\n",
                           ability.getManaCost(), paidCommand, unpaidCommand));
               }
             else //computer
               {
                   while(ComputerUtil.canPayCost(ability)) ComputerUtil.playNoStack(ability);
                   push(sa);
               }
        }
       
     }
  }
  public int size()
  {
    return stack.size();
  }
  // Beached As Start
  public void push(SpellAbility sp)
  {
       if (stack.size() == 0) {
           StackMax = 0;
        }
    stack.add(0, sp);

    this.updateObservers();
    if(sp.isSpell())
    {
        SpellStack.add(0, sp);
       StackMax = StackMax + 1;
          Phase.StormCount = Phase.StormCount + 1;   
       //attempt to counter human spell
       if (sp.getSourceCard().getController().equals(Constant.Player.Human) &&
          CardFactoryUtil.isCounterable(sp.getSourceCard()) )
          ComputerAI_counterSpells2.counter_Spell(sp);   
       //put code for Standstill here
       GameActionUtil.executePlayCardEffects(sp);
       
    }
  }
 // Beached As End
 // Beached As Start
  public SpellAbility pop()
  {
   
    SpellAbility sp = (SpellAbility) stack.remove(0);
    if(sp.isSpell())
    {
    SpellStack.remove(0);
    }
   StackCurrent = SpellStack.size();
    this.updateObservers();
    return sp;
  }
  // Beached As End
  //index = 0 is the top, index = 1 is the next to top, etc...
  public SpellAbility peek(int index)
  {
    return (SpellAbility) stack.get(index);
  }
  public SpellAbility peek()
  {
    return peek(0);
  }
  public ArrayList<Card> getSourceCards()
  {
    ArrayList<Card> a = new ArrayList<Card>();
    Iterator<SpellAbility> it = stack.iterator();
    while(it.hasNext())
      a.add(((SpellAbility)it.next()).getSourceCard());

    return a;
  }
  // Beached As Start
public void setStormCount(Object stormCount) {
   StormCount = stormCount;
}

public Object getStormCount() {
   return StormCount;
}
 // Beached As End
}

Phase.java

Code: Select all

package forge;


import java.util.Observer;


public class Phase extends MyObservable {
    private int    phaseIndex;
    private int    turn;
    // Beached As Start
    static int      StormCount;
    // Beached As End   
    private int    humanExtraTurns;
    private int    computerExtraTurns;
   
    private String phases[][] = {
            //human's turn
            {Constant.Player.Human, Constant.Phase.Untap},
//   {Constant.Player.Human    , Constant.Phase.Upkeep}                                ,
            {Constant.Player.Human, Constant.Phase.Draw},
            {Constant.Player.Human, Constant.Phase.Main1},
            {Constant.Player.Human, Constant.Phase.Combat_Declare_Attackers},
            {Constant.Player.Human, Constant.Phase.Combat_Declare_Attackers_InstantAbility},
            {Constant.Player.Computer, Constant.Phase.Combat_Declare_Blockers},
            {Constant.Player.Human, Constant.Phase.Combat_Declare_Blockers_InstantAbility},
            {Constant.Player.Computer, Constant.Phase.Combat_Declare_Blockers_InstantAbility},
            {Constant.Player.Computer, Constant.Phase.Combat_After_Declare_Blockers},
            {Constant.Player.Human, Constant.Phase.Combat_FirstStrikeDamage}, //TODO: need to allow computer to have priority (play instants and abilities).
            {Constant.Player.Human, Constant.Phase.Combat_Damage},
            {Constant.Player.Human, Constant.Phase.End_Of_Combat},
            {Constant.Player.Human, Constant.Phase.Main2},
            {Constant.Player.Human, Constant.Phase.At_End_Of_Turn},
//   {Constant.Player.Computer , Constant.Phase.End_Of_Turn}                           ,
            {Constant.Player.Human, Constant.Phase.Until_End_Of_Turn},
            {Constant.Player.Human, Constant.Phase.Cleanup},
           
            //computer's turn
            {Constant.Player.Computer, Constant.Phase.Untap},
            {Constant.Player.Computer, Constant.Phase.Draw},
            {Constant.Player.Computer, Constant.Phase.Main1},
            {Constant.Player.Human, Constant.Phase.Combat_Before_Declare_Attackers_InstantAbility},
            {Constant.Player.Computer, Constant.Phase.Combat_Declare_Attackers},
            {Constant.Player.Human, Constant.Phase.Combat_Declare_Attackers_InstantAbility},
            {Constant.Player.Human, Constant.Phase.Combat_Declare_Blockers},
            {Constant.Player.Computer, Constant.Phase.Combat_Declare_Blockers_InstantAbility},
            {Constant.Player.Human, Constant.Phase.Combat_Declare_Blockers_InstantAbility},
            {Constant.Player.Computer, Constant.Phase.Combat_After_Declare_Blockers},
            {Constant.Player.Human, Constant.Phase.Combat_FirstStrikeDamage}, //TODO: need to allow computer to have priority (play instants and abilities).
            {Constant.Player.Human, Constant.Phase.Combat_Damage},
            {Constant.Player.Human, Constant.Phase.End_Of_Combat},
            {Constant.Player.Computer, Constant.Phase.Main2},
            {Constant.Player.Computer, Constant.Phase.At_End_Of_Turn},
            {Constant.Player.Human, Constant.Phase.End_Of_Turn},
            {Constant.Player.Computer, Constant.Phase.Until_End_Of_Turn},
            {Constant.Player.Computer, Constant.Phase.Cleanup},};
   
    public Phase() {
        reset();
    }
   
    public void reset() {
        turn = 1;
        phaseIndex = 0;
        humanExtraTurns = 0;
        computerExtraTurns = 0;
        this.updateObservers();
    }
   
    public void setPhase(String phase, String player) {
        phaseIndex = findIndex(phase, player);
        this.updateObservers();
    }
   
    public void nextPhase() {
       
        //System.out.println("current active Player: " + getActivePlayer()); 
        //experimental, add executeCardStateEffects() here:
        for(String effect:AllZone.StaticEffects.getStateBasedMap().keySet()) {
            Command com = GameActionUtil.commands.get(effect);
            com.execute();
        }
       
        GameActionUtil.executeCardStateEffects();
       
        //for debugging: System.out.print("this phase - " +getActivePlayer() +" " +getPhase()+", next phase - ");
        needToNextPhase = false;
       

        if(getPhase().equals(Constant.Phase.Combat_Damage)) {
            if(AllZone.Stack.size() != 0) {
                return;
            }
        }
       
        //empty manapool:
        //CardList cl = new CardList(AllZone.getZone(Constant.Zone.Play, Constant.Player.Human).getCards());
        //cl = cl.getName("Mana Pool");
        //if (cl.size() > 0)
        //{
        //   Card c = cl.get(0);
        //   c.setExtrinsicKeyword(new ArrayList<String>());
        //}
       

        AllZone.ManaPool.clear();
       
        //time vault:
        if((is(Constant.Phase.Cleanup, Constant.Player.Human) && humanExtraTurns >= 0)
                || (is(Constant.Phase.Cleanup, Constant.Player.Computer) && computerExtraTurns >= 0)) {
            String player = getActivePlayer();
            String opponent = AllZone.GameAction.getOpponent(player);
            CardList list = CardFactoryUtil.getCards("Time Vault", opponent);
            list = list.filter(new CardListFilter() {
                public boolean addCard(Card c) {
                    return c.isTapped();
                }
            });
           
            for(int i = 0; i < list.size(); i++) {
                final Card crd = list.get(i);
               
                /*
                Ability ability = new Ability(list.get(i), "0")
                {
                   public void resolve()
                   {
                      String controller = crd.getController();
                      if (controller.equals(Constant.Player.Human))
                         humanExtraTurns--;
                      else
                         computerExtraTurns--;
                      
                      crd.untap();
                   }
                };
                ability.setStackDescription(crd + " - skip this turn instead, untap Time Vault.");
                */

                if(player.equals(Constant.Player.Computer)) {
                    String[] choices = {"Yes", "No"};
                    Object q = null;
                    q = AllZone.Display.getChoiceOptional("Untap " + crd + "?", choices);
                    if(q.equals("Yes")) {
                        //AllZone.Stack.add(ability);
                        humanExtraTurns--;
                        crd.untap();
                    }
                   
                }
            }
        }
       
        //if (getPhase().equals(Constant.Phase.Cleanup) && extraTurns > 0)
        if((is(Constant.Phase.Cleanup, Constant.Player.Human) && humanExtraTurns > 0)
                || (is(Constant.Phase.Cleanup, Constant.Player.Computer) && computerExtraTurns > 0)) {
            //System.out.println("CLEANUP!");
            String player = getActivePlayer();
            String opponent = AllZone.GameAction.getOpponent(player);
           
            if(player.equals(Constant.Player.Computer)) computerExtraTurns--;
            else humanExtraTurns--;
           
            AllZone.GameAction.setLastPlayerToDraw(opponent);
            setPhase(Constant.Phase.Untap, player);
        } else if((is(Constant.Phase.Cleanup, Constant.Player.Computer) && humanExtraTurns < 0)
                || (is(Constant.Phase.Cleanup, Constant.Player.Human) && computerExtraTurns < 0)) {
            String player = getActivePlayer();
            String opp = AllZone.GameAction.getOpponent(player);
            if(player.equals(Constant.Player.Computer)) humanExtraTurns++;
            else computerExtraTurns++;
           
            AllZone.GameAction.setLastPlayerToDraw(opp);
            setPhase(Constant.Phase.Untap, player);
        } else {
            phaseIndex++;
            if(phases.length <= phaseIndex) phaseIndex = 0;
        }
       
        // Beached As Start
        //if(getPhase().equals(Constant.Phase.Untap)) {
        if(is(Constant.Phase.Untap, Constant.Player.Human)) {
           StormCount = 0;
            turn++;
            /*
            if (humanExtraTurns > 0)
              humanExtraTurns--;
            else if(humanExtraTurns < 0)
              humanExtraTurns++;
              */
        } else if(is(Constant.Phase.Untap, Constant.Player.Computer)) {
           StormCount = 0;
            AllZone.GameInfo.setComputerPlayedFirstLandThisTurn(false);
            turn++;
            /*
            if (computerExtraTurns > 0)
              computerExtraTurns--;
            else if(computerExtraTurns < 0)
              computerExtraTurns++;
              */
        }
        if(is(Constant.Phase.Main1, Constant.Player.Human)) {
           if(turn == 1) {
           StormCount = 0;
           }
        }
        // Beached As End
        //for debugging: System.out.println(getPhase());
       
        //System.out.print("");
        this.updateObservers();
        if(AllZone.Phase != null) {
            if(AllZone.Phase.isNeedToNextPhase() == true) {
                AllZone.Phase.setNeedToNextPhase(false);
                AllZone.Phase.nextPhase();
            }
        }
    }
   
    public synchronized boolean is(String phase, String player) {
        return (getPhase().equals(phase) && getActivePlayer().equals(player));
    }
   
    private int findIndex(String phase, String player) {
        for(int i = 0; i < phases.length; i++) {
            if(player.equals(phases[i][0]) && phase.equals(phases[i][1])) return i;
        }
        throw new RuntimeException("Phase : findIndex() invalid argument, phase = " + phase + " player = "
                + player);
    }
   
    public String getActivePlayer() {
        //hack
        return phases[phaseIndex][0];
    }
   
    public String getPhase() {
        return phases[phaseIndex][1];
    }
   
    public int getTurn() {
        return turn;
    }
   
    public void setTurn(int in_turn) {
        turn = in_turn;
    }
   
    public void addExtraTurn(String player) {
        if(player.equals(Constant.Player.Human)) humanExtraTurns++;
        else computerExtraTurns++;
    }
   
    public void subtractExtraTurn(String player) {
        if(player.equals(Constant.Player.Human)) humanExtraTurns--;
        else computerExtraTurns--;
    }
   
    public int getExtraTurns(String player) {
        if(player.equals(Constant.Player.Human)) return humanExtraTurns;
        else return computerExtraTurns;
    }
   
    public void setExtraTurns(int i, String player) {
        if(player.equals(Constant.Player.Human)) humanExtraTurns = i;
        else computerExtraTurns = i;
    }
   
    public static void main(String args[]) {
        Phase phase = new Phase();
        for(int i = 0; i < phase.phases.length + 3; i++) {
            System.out.println(phase.getActivePlayer() + " " + phase.getPhase());
            phase.nextPhase();
        }
    }
   
    @Override
    public void addObserver(Observer o) {
        super.deleteObservers();
        super.addObserver(o);
    }
   
    boolean needToNextPhase = false;
   
    public void setNeedToNextPhase(boolean needToNextPhase) {
        this.needToNextPhase = needToNextPhase;
    }
   
    public boolean isNeedToNextPhase() {
        return this.needToNextPhase;
    }
   
    //This should only be true four times! that is for the initial nextPhases in MyObservable
    int needToNextPhaseInit = 0;
   
    public boolean isNeedToNextPhaseInit() {
        needToNextPhaseInit++;
        if(needToNextPhaseInit <= 4) {
            return true;
        }
        return false;
    }
   

}
Change Empty the Warrens in CardFactory.java to:

Code: Select all
        //*************** START *********** START **************************
        else if(cardName.equals("Empty the Warrens")) {
            SpellAbility spell = new Spell(card) {
                private static final long serialVersionUID = 1439643889038241969L;
               
                @Override
                public void resolve() {
                        for(int i = 0; i < 2 * (Phase.StormCount - MagicStack.StackMax + MagicStack.StackCurrent + 1); i++)
                            CardFactoryUtil.makeToken("Goblin", "R 1 1 Goblin", card, "R", new String[] {
                                    "Creature", "Goblin"}, 1, 1, new String[] {""});                   
                   
                }//resolve()
            };
            card.clearSpellAbility();
            card.addSpellAbility(spell);
        }//*************** END ************ END **************************
Beached As
Programmer
 
Posts: 110
Joined: 23 Feb 2010, 07:48
Has thanked: 0 time
Been thanked: 0 time

Re: Code from Beached As

Postby Beached As » 01 May 2010, 20:32

Lotus Petal : Tempest Rare (Copied from Black Lotus)

Add to CardFactory.java

Code: Select all
        //*************** START *********** START **************************
        else if(cardName.equals("Lotus Petal")) {
            final Ability_Tap ability = new Ability_Tap(card, "0") {
                private static final long serialVersionUID = 8394047173115959008L;
               
               
                @Override
                public boolean canPlayAI() {
                    return false;
                }
               
                @Override
                public void resolve() {
                    if(card.getController().equals(Constant.Player.Human)) {
                        //CardList list = new CardList(AllZone.getZone(Constant.Zone.Play, Constant.Player.Human).getCards());
                        //list = list.getName("Mana Pool");
                        Card mp = AllZone.ManaPool;//list.getCard(0);
                       
                        String color = "";
                       
                        Object o = AllZone.Display.getChoice("Choose mana color", Constant.Color.Colors);
                        color = (String) o;
                       
                        if(color.equals("white")) color = "W";
                        else if(color.equals("blue")) color = "U";
                        else if(color.equals("black")) color = "B";
                        else if(color.equals("red")) color = "R";
                        else if(color.equals("green")) color = "G";
                        else color = "1";
                       

                        //System.out.println("ManaPool:"+color+":");
                            mp.addExtrinsicKeyword("ManaPool:" + color);
                       
                        //AllZone.GameAction.sacrifice(card);
                    }
                }
            };
            ability.setDescription("tap, Sacrifice Lotus Petal: Add one mana of any one color to your mana pool.");
            ability.setStackDescription("Adds 1 mana of any one color to your mana pool");
           

            Input sac = new Input() {
                private static final long serialVersionUID = -4501025947115838818L;
               
                @Override
                public void showMessage() {
                    AllZone.GameAction.sacrifice(card);
                    ability.resolve();
                    stop();
                }
            };//Input
            ability.setBeforePayMana(sac);
           
            card.addSpellAbility(ability);
        }//*************** END ************ END **************************   
Add to Cards.txt

Code: Select all
Lotus Petal
0
Artifact
no text
URL

Code: Select all
http://www.wizards.com/global/images/magic/general/lotus_petal.jpg
Beached As
Programmer
 
Posts: 110
Joined: 23 Feb 2010, 07:48
Has thanked: 0 time
Been thanked: 0 time

Re: Code from Beached As

Postby Beached As » 01 May 2010, 20:35

Lion's Eye Diamond : Mirage Rare (Copied from Black Lotus)

Add to CardFactory.java

Code: Select all
        //*************** START *********** START **************************
        else if(cardName.equals("Lion's Eye Diamond")) {
            final Ability_Tap ability = new Ability_Tap(card, "0") {
                private static final long serialVersionUID = 8394003913115959008L;
               
               
                @Override
                public boolean canPlayAI() {
                    return false;
                }
               
                @Override
                public void resolve() {
                    if(card.getController().equals(Constant.Player.Human)) {
                        CardList hand = new CardList(AllZone.getZone(Constant.Zone.Hand, Constant.Player.Human).getCards());
                    for (int i=0; i < hand.size();i++)
                       AllZone.GameAction.discardRandom(Constant.Player.Human);
                        //CardList list = new CardList(AllZone.getZone(Constant.Zone.Play, Constant.Player.Human).getCards());
                        //list = list.getName("Mana Pool");
                        Card mp = AllZone.ManaPool;//list.getCard(0);
                       
                        String color = "";
                       
                        Object o = AllZone.Display.getChoice("Choose mana color", Constant.Color.Colors);
                        color = (String) o;
                       
                        if(color.equals("white")) color = "W";
                        else if(color.equals("blue")) color = "U";
                        else if(color.equals("black")) color = "B";
                        else if(color.equals("red")) color = "R";
                        else if(color.equals("green")) color = "G";
                        else color = "1";
                       

                        //System.out.println("ManaPool:"+color+":");
                        for(int i = 0; i < 3; i++)
                            mp.addExtrinsicKeyword("ManaPool:" + color);
                       
                        //AllZone.GameAction.sacrifice(card);
                    }
                }
            };
            ability.setDescription("tap, Sacrifice Lion's Eye Diamond: Discard your hand and add three mana of any one color to your mana pool.");
            ability.setStackDescription("Discard your hand and adds 3 mana of any one color to your mana pool");
           

            Input sac = new Input() {
                private static final long serialVersionUID = -4503945947115838818L;
               
                @Override
                public void showMessage() {
                    AllZone.GameAction.sacrifice(card);
                    ability.resolve();
                    stop();
                }
            };//Input
            ability.setBeforePayMana(sac);
           
            card.addSpellAbility(ability);
        }//*************** END ************ END **************************
Add to Cards.txt

Code: Select all
Lion's Eye Diamond
0
Artifact
no text
URL:

Code: Select all
http://www.wizards.com/global/images/magic/general/lions_eye_diamond.jpg
Beached As
Programmer
 
Posts: 110
Joined: 23 Feb 2010, 07:48
Has thanked: 0 time
Been thanked: 0 time

Re: Code from Beached As

Postby Beached As » 01 May 2010, 20:46

Windfall : Urza's Saga Uncommon ( Based on Wheel of Fortune )

Add to CardFactory.java

Code: Select all
        //*************** START *********** START **************************
        else if(cardName.equals("Windfall")) {
            final SpellAbility spell = new Spell(card) {
                private static final long serialVersionUID = -7707012960887790709L;
               
                @Override
                public void resolve() {
                    discardDraw(Constant.Player.Human);
                    discardDraw(Constant.Player.Computer);
                }//resolve()
               
                void discardDraw(String player) {
                    PlayerZone hand = AllZone.getZone(Constant.Zone.Hand, player);
                    CardList Hhand = new CardList(AllZone.getZone(Constant.Zone.Hand, Constant.Player.Human).getCards());
                    CardList Chand = new CardList(AllZone.getZone(Constant.Zone.Hand, Constant.Player.Computer).getCards());
                    int draw;
                    if(Hhand.size() >= Chand.size()) {
                       draw = Hhand.size();
                    } else {
                       draw = Chand.size();                      
                    }
                    Card[] c = hand.getCards();
                    for(int i = 0; i < c.length; i++)
                        AllZone.GameAction.discard(c[i]);
                   
                    for(int i = 0; i < draw; i++)
                        AllZone.GameAction.drawCard(player);
                }
            };//SpellAbility
            card.clearSpellAbility();
            card.addSpellAbility(spell);
        }//*************** END ************ END **************************
Add to Cards.txt

Code: Select all
Windfall
2 U
Sorcery
Each player discards his or her hand, then draws cards equal to the greatest number of cards a player discarded this way.
URL:

Code: Select all
http://www.wizards.com/global/images/magic/general/windfall.jpg
Beached As
Programmer
 
Posts: 110
Joined: 23 Feb 2010, 07:48
Has thanked: 0 time
Been thanked: 0 time

Re: Code from Beached As

Postby Chris H. » 01 May 2010, 21:05

Beached As wrote:Lotus Petal : Tempest Rare (Copied from Black Lotus)
`
I think that someone may have recently added this card to the SVN. I could be mistaken ... a lot of cards have been added over the last couple of weeks. I am pretty sure that your other recent submissions are not yet added. Thank you. :D
User avatar
Chris H.
Forge Moderator
 
Posts: 6320
Joined: 04 Nov 2008, 12:11
Location: Mac OS X Yosemite
Has thanked: 644 times
Been thanked: 643 times

Re: Code from Beached As

Postby DennisBergkamp » 01 May 2010, 21:21

Ah yes, I actually added it through the keyword, so it's an actual mana ability. I also converted Black Lotus to use the keyword...
User avatar
DennisBergkamp
AI Programmer
 
Posts: 2602
Joined: 09 Sep 2008, 15:46
Has thanked: 0 time
Been thanked: 0 time

Re: Code from Beached As

Postby Beached As » 01 May 2010, 21:25

Yeah so many cards have been added, its hard to keep up.

Forbidden Orchard : Champions of Kamigawa Rare

Add to CardFactoryLands.java

Code: Select all
        //*************** START *********** START **************************
        else if(cardName.equals("Forbidden Orchard")) {
            final Ability_Tap ability = new Ability_Tap(card, "0") {
                private static final long serialVersionUID = 8394019533115959008L;
               
               
                @Override
                public boolean canPlayAI() {
                    return false;
                }
               
                @Override
                public void resolve() {
                    if(card.getController().equals(Constant.Player.Human)) {
                        //CardList list = new CardList(AllZone.getZone(Constant.Zone.Play, Constant.Player.Human).getCards());
                        //list = list.getName("Mana Pool");
                        Card mp = AllZone.ManaPool;//list.getCard(0);
                       
                        String color = "";
                       
                        Object o = AllZone.Display.getChoice("Choose mana color", Constant.Color.Colors);
                        color = (String) o;
                       
                        if(color.equals("white")) color = "W";
                        else if(color.equals("blue")) color = "U";
                        else if(color.equals("black")) color = "B";
                        else if(color.equals("red")) color = "R";
                        else if(color.equals("green")) color = "G";
                        else color = "1";
                       

                        //System.out.println("ManaPool:"+color+":");
                            mp.addExtrinsicKeyword("ManaPool:" + color);
                            card.tap();
                            CardFactoryUtil.makeToken("Forbidden Orchard Spirit", "1 1 1 Spirit",
                                    AllZone.GameAction.getOpponent(card.getController()), "", new String[] {
                                            "Creature", "Spirit"}, 1, 1, new String[] {""});                       
                        //AllZone.GameAction.sacrifice(card);
                    }
                }
            };
            ability.setDescription("tap: Add one mana of any color to your mana pool. Whenever you tap Forbidden Orchard for mana, put a 1/1 colorless Spirit creature token onto the battlefield under target opponent's control");
            ability.setStackDescription("Adds 1 mana of any one color to your mana pool and put a 1/1 colorless Spirit creature token onto the battlefield under target opponent's control");
           

            Input sac = new Input() {
                private static final long serialVersionUID = -4501025012535838818L;
               
                @Override
                public void showMessage() {
                    ability.resolve();
                    stop();
                }
            };//Input
            ability.setBeforePayMana(sac);
           
            card.addSpellAbility(ability);
        }//*************** END ************ END **************************
Add to Cards.txt

Code: Select all
Forbidden Orchard
no cost
Land
no text
URL:
Code: Select all
http://www.wizards.com/global/images/magic/general/forbidden_orchard.jpg
Beached As
Programmer
 
Posts: 110
Joined: 23 Feb 2010, 07:48
Has thanked: 0 time
Been thanked: 0 time

Re: Code from Beached As

Postby Beached As » 01 May 2010, 21:29

Ah yes, I actually added it through the keyword, so it's an actual mana ability. I also converted Black Lotus to use the keyword...
oh lol, well Lotus Petal didn't take long to code with Black Lotus lying around
Beached As
Programmer
 
Posts: 110
Joined: 23 Feb 2010, 07:48
Has thanked: 0 time
Been thanked: 0 time

Re: Code from Beached As

Postby Chris H. » 01 May 2010, 21:59

Beached As wrote:Yeah so many cards have been added, its hard to keep up.
`
At some point you may want to try to install a matching set of subclipse and Subversion for your copy of Eclipse. This will allow you to access our SVN. You will be able to keep your local code base up to date with our recent code additions. :wink:
User avatar
Chris H.
Forge Moderator
 
Posts: 6320
Joined: 04 Nov 2008, 12:11
Location: Mac OS X Yosemite
Has thanked: 644 times
Been thanked: 643 times

Re: Code from Beached As

Postby Beached As » 02 May 2010, 02:45

Yep i just installed subclipse and subversion. Hopefully i've done it right but i can see everything up to revision 924 (the most recent one). Should be easier to see whats going on :)

I am getting more familiar with the code but i don't think i'm up to committer status yet, my code is rubbish and long compared to most of the real programmers on here. I guess practice makes perfect... so i'll keep practicing
Beached As
Programmer
 
Posts: 110
Joined: 23 Feb 2010, 07:48
Has thanked: 0 time
Been thanked: 0 time

Re: Code from Beached As

Postby MageKing17 » 02 May 2010, 06:52

Rob Cashwalker wrote:Somewhere, the stack object calls to the resolve method of any spell or ability on the stack. (Search for ".resolve")
It would be there, that a check should be made to see if the item being resolved is a Spell or an Ability. How, I'm not too sure, since they're derived from the same classes.... But that would be the proper location to increment a storm count.
The proper time to increment the storm count is upon a spell being cast, not resolving. Since the same event is monitored by a lot of cards (Angel's Feather, Contemplation, et cetera), storm shouldn't be that hard to implement.
User avatar
MageKing17
Programmer
 
Posts: 473
Joined: 12 Jun 2008, 20:40
Has thanked: 5 times
Been thanked: 9 times

Re: Code from Beached As

Postby Beached As » 02 May 2010, 08:05

Oath of Druids : Exodus Rare
The code is rather long, perhaps it could be simplified. This has been tested.

Add to GameActionUtil.java

Code: Select all
   private static void upkeep_Oath_of_Druids() {
      final String player = AllZone.Phase.getActivePlayer();
      String opponent = AllZone.GameAction.getOpponent(player);
        PlayerZone PlayerPlayZone = AllZone.getZone(Constant.Zone.Play, player);
      PlayerZone opponentPlayZone = AllZone.getZone(Constant.Zone.Play, opponent);
      CardList Oath = new CardList(PlayerPlayZone.getCards());
      Oath = Oath.getName("Oath of Druids");

      if(0 < Oath.size()) {
         for(int i = 0; i < Oath.size(); i++) {
            Ability ability = new Ability(Oath.get(i), "0") {
               @Override
               public void resolve() {   
                  String player = AllZone.Phase.getActivePlayer();
                  String opponent = AllZone.GameAction.getOpponent(player);
                    PlayerZone PlayerPlayZone = AllZone.getZone(Constant.Zone.Play, player);
                    CardList PlayerCreatureList = new CardList(PlayerPlayZone.getCards());
                    PlayerCreatureList = PlayerCreatureList.getType("Creature");
                  PlayerZone opponentPlayZone = AllZone.getZone(Constant.Zone.Play, opponent);
                    CardList opponentCreatureList = new CardList(opponentPlayZone.getCards());
                    opponentCreatureList = opponentCreatureList.getType("Creature");
                    PlayerZone grave = AllZone.getZone(Constant.Zone.Graveyard, player);
                    PlayerZone lib = AllZone.getZone(Constant.Zone.Library, player);
                    CardList libList = new CardList(lib.getCards());
                    if(PlayerCreatureList.size() < opponentCreatureList.size()) {
                      String[] choices = {"Yes", "No"};
                      Object q = null;
                      q = AllZone.Display.getChoiceOptional("Use Oath of Druids?", choices);
                      if(q == null || q.equals("No"));
                      else {
                        int max = libList.size();
                        int stop = 0;                 

                        for(int i = 0; i < max; i++) {
                            Card c = libList.get(i);
                            if(c.getType().contains("Creature")) {
                                if(stop == 0) {
                                    AllZone.GameAction.moveTo(PlayerPlayZone, c);
                                   stop = 1;
                                }         
                            } else if(stop == 0) {
                               lib.remove(c);
                               grave.add(c);
                            }
                        }
                        }
                    }
               }
            };// Ability
               ability.setStackDescription("At the beginning of each player's upkeep, that player chooses target player who controls more creatures than he or she does and is his or her opponent. The first player may reveal cards from the top of his or her library until he or she reveals a creature card. If he or she does, that player puts that card onto the battlefield and all other cards revealed this way into his or her graveyard.");
               AllZone.Stack.add(ability);
            }
         
      }// if
      CardList Oath2 = new CardList(opponentPlayZone.getCards());
      Oath2 = Oath2.getName("Oath of Druids");

      if(0 < Oath2.size()) {
         for(int i = 0; i < Oath2.size(); i++) {
            Ability ability = new Ability(Oath2.get(i), "0") {
               @Override
               public void resolve() {   
                  String player = AllZone.Phase.getActivePlayer();
                  String opponent = AllZone.GameAction.getOpponent(player);
                    PlayerZone PlayerPlayZone = AllZone.getZone(Constant.Zone.Play, player);
                    CardList PlayerCreatureList = new CardList(PlayerPlayZone.getCards());
                    PlayerCreatureList = PlayerCreatureList.getType("Creature");
                  PlayerZone opponentPlayZone = AllZone.getZone(Constant.Zone.Play, opponent);
                    CardList opponentCreatureList = new CardList(opponentPlayZone.getCards());
                    opponentCreatureList = opponentCreatureList.getType("Creature");
                    PlayerZone grave = AllZone.getZone(Constant.Zone.Graveyard, player);
                    PlayerZone lib = AllZone.getZone(Constant.Zone.Library, player);
                    CardList libList = new CardList(lib.getCards());
                    if(PlayerCreatureList.size() < opponentCreatureList.size()) {
                      String[] choices = {"Yes", "No"};
                      Object q = null;
                      q = AllZone.Display.getChoiceOptional("Use Oath of Druids?", choices);
                      if(q == null || q.equals("No"));
                      else {
                        int max = libList.size();
                        int stop = 0;                 

                        for(int i = 0; i < max; i++) {
                            Card c = libList.get(i);
                            if(c.getType().contains("Creature")) {
                                if(stop == 0) {
                                    AllZone.GameAction.moveTo(PlayerPlayZone, c);
                                   stop = 1;
                                }         
                            } else if(stop == 0) {
                               lib.remove(c);
                               grave.add(c);
                            }
                        }
                        }
                    }
                   
               }
            };// Ability
               ability.setStackDescription("At the beginning of each player's upkeep, that player chooses target player who controls more creatures than he or she does and is his or her opponent. The first player may reveal cards from the top of his or her library until he or she reveals a creature card. If he or she does, that player puts that card onto the battlefield and all other cards revealed this way into his or her graveyard.");
               AllZone.Stack.add(ability);
            }
         
      }// if
   }// upkeep_Oath_of_Druids()
Also need to add "upkeep_Oath_of_Druids();" (without commas) in executeUpkeepEffects() in GameActionUtil.java

Add to Cards.txt

Code: Select all
Oath of Druids
1 G
Enchantment
At the beginning of each player's upkeep, that player chooses target player who controls more creatures than he or she does and is his or her opponent. The first player may reveal cards from the top of his or her library until he or she reveals a creature card. If he or she does, that player puts that card onto the battlefield and all other cards revealed this way into his or her graveyard.
URL:
Code: Select all
http://www.wizards.com/global/images/magic/general/oath_of_druids.jpg
Beached As
Programmer
 
Posts: 110
Joined: 23 Feb 2010, 07:48
Has thanked: 0 time
Been thanked: 0 time

Re: Code from Beached As

Postby Beached As » 16 May 2010, 17:37

Affa Guard Hound : Rise of Eldrazi Uncommon
Based on Inner-Flame Acolyte. This has been tested
Add to CardFactory_Creatures.java
Code: Select all
    //*************** START *********** START **************************
        else if(cardName.equals("Affa Guard Hound")) {
                final CommandReturn getCreature = new CommandReturn() {
                    //get target card, may be null
                    public Object execute() {
                        Combat combat = ComputerUtil.getAttackers();
                        Card[] c = combat.getAttackers();
                        CardList list = new CardList();
                       
                        if(c.length == 0) {
                            list.addAll(AllZone.Computer_Play.getCards());
                            list = list.filter(new CardListFilter() {
                                public boolean addCard(Card c) {
                                    return c.isCreature();
                                }
                            });
                           
                            if(list.size() == 0) return card;
                            else {
                                CardListUtil.sortAttack(list);
                                CardListUtil.sortFlying(list);
                               
                                for(int i = 0; i < list.size(); i++)
                                    if(list.get(i).isUntapped()) return list.get(i);
                               
                                return list.get(0);
                            }
                        }
                       
                        return c[0];
                    }//execute()
                };//CommandReturn
               
                final SpellAbility ability = new Ability(card, "0") {
                    @Override
                    public void resolve() {
                        final Card c = getTargetCard();
                       
                        if(AllZone.GameAction.isCardInPlay(c) && CardFactoryUtil.canTarget(card, c)) {
                            c.addTempDefenseBoost(3);
                           
                            AllZone.EndOfTurn.addUntil(new Command() {
                                private static final long serialVersionUID = -6478141025919509688L;
                               
                                public void execute() {
                                    c.addTempDefenseBoost(-3);
                                }
                            });
                        }//if
                    }//resolve()
                };//SpellAbility
                Command intoPlay = new Command() {
                    private static final long serialVersionUID = -4514602963470596654L;
                   
                    public void execute() {
                        if(card.getController().equals(Constant.Player.Human)) {
                            AllZone.InputControl.setInput(CardFactoryUtil.input_targetCreature(ability));
                        } else//computer
                        {
                            Object o = getCreature.execute();
                            if(o != null)//should never happen, but just in case
                            {
                                ability.setTargetCard((Card) o);
                                AllZone.Stack.add(ability);
                            }
                        }//else
                    }//execute()
                };
                card.addComesIntoPlayCommand(intoPlay);
               
                card.clearSpellAbility();
                card.addSpellAbility(new Spell_Permanent(card) {
                    private static final long serialVersionUID = 7153795935713327863L;
                   
                    @Override
                    public boolean canPlayAI() {
                        Object o = getCreature.execute();
                       
                        return (o != null) && AllZone.getZone(getSourceCard()).is(Constant.Zone.Hand);
                    }
                });
            }//*************** END ************ END ************************** 
add to ComputerAI_General.java

Code: Select all
        play.add("Affa Guard Hound");
add to cards.txt

Code: Select all
Affa Guard Hound
2 W 
Creature Hound
When Affa Guard Hound comes into play, target creature gets +0/+3 until end of turn.
2/2
Flash
URL
Code: Select all
http://www.wizards.com/global/images/magic/general/affa_guard_hound.jpg
Beached As
Programmer
 
Posts: 110
Joined: 23 Feb 2010, 07:48
Has thanked: 0 time
Been thanked: 0 time

Re: Code from Beached As

Postby Chris H. » 16 May 2010, 17:42

I see that Forbidden Orchard was merged into rev 1056. Thank you Dennis. I have been fairly busy but I spent some time trying to merge Oath of Druids and Doomed Necromancer.

I had problems with Oath of Druids, the order for the upkeep costs appear to be dependent on issues that I do not understand.

Doomed Necromancer works but uses an add Spell Ability form that I am not familiar with ... I was not sure how to resolve the issue. Stitch Together and Windfall may work as is but I have not yet had a chance to investigate.

I would like to thank Beached As for his submissions and I would like to apologize for the dev team. We sometimes get preoccupied with other areas of Forge and it can be hard to focus on other areas. :wink:
User avatar
Chris H.
Forge Moderator
 
Posts: 6320
Joined: 04 Nov 2008, 12:11
Location: Mac OS X Yosemite
Has thanked: 644 times
Been thanked: 643 times

PreviousNext

Return to Developer's Corner

Who is online

Users browsing this forum: No registered users and 30 guests

Main Menu

User Menu

Our Partners


Who is online

In total there are 30 users online :: 0 registered, 0 hidden and 30 guests (based on users active over the past 10 minutes)
Most users ever online was 9298 on 10 Oct 2025, 12:54

Users browsing this forum: No registered users and 30 guests

Login Form