- Fixed Pit Scorpion.

- Fixed some of the "Sacrifice a creature" spells ("destroy" effects would sometimes not happen). 
- Added a few cards: Propaganda, Ghostly Prison, Windborn Muse, Arctic Nishoba, Peacekeeper, Marsh Viper.
- Yet another fix to Force of Will.
This commit is contained in:
jendave
2011-08-06 03:10:05 +00:00
parent 739b50e2dd
commit 9f3fdf429f
11 changed files with 197 additions and 30 deletions

View File

@@ -1,3 +1,41 @@
Windborn Muse
3 W
Creature Spirit
Creatures can't attack you unless their controller pays 2 for each creature he or she controls that's attacking you.
2/3
Flying
Ghostly Prison
2 W
Enchantment
Creatures can't attack you unless their controller pays 2 for each creature he or she controls that's attacking you.
Propaganda
2 U
Enchantment
Creatures can't attack you unless their controller pays 2 for each creature he or she controls that's attacking you.
Peacekeeper
2 W
Creature Human
Creatures can't attack
1/1
Upkeep:1 W
Arctic Nishoba
5 G
Creature Cat
When Arctic Nishoba is put into a graveyard from the battlefield, you gain 2 life for each age counter on it.
6/6
Trample
Cumulative upkeep:GW
Marsh Viper
3 G
Creature Snake
Whenever Marsh Viper deals damage to an opponent, that player gets two poison counters.
1/2
Force of Will
3 U U
Instant
@@ -705,8 +743,9 @@ no text
Pit Scorpion
2 B
Creature Scorpion
Whenever this creature deals damage to a player, that player gets a poison counter.
no text
1/1
Whenever this creature deals damage to a player, that player gets a poison counter.
Bridge from Below
B B B

View File

@@ -339,7 +339,7 @@
<int>255</int>
<int>533</int>
<int>901</int>
<int>145</int>
<int>146</int>
</object>
</void>
<void property="name">
@@ -358,7 +358,7 @@
<void property="bounds">
<object class="java.awt.Rectangle">
<int>255</int>
<int>678</int>
<int>679</int>
<int>901</int>
<int>10</int>
</object>
@@ -373,9 +373,9 @@
<void property="bounds">
<object class="java.awt.Rectangle">
<int>255</int>
<int>688</int>
<int>689</int>
<int>901</int>
<int>139</int>
<int>138</int>
</object>
</void>
<void property="name">

View File

@@ -17904,7 +17904,8 @@ return land.size() > 1 && CardFactoryUtil.AI_isMainPhase();
public void selectButtonCancel() {stop();}
public void selectCard(Card c, PlayerZone zone)
{
if(CardUtil.getColors(c).contains(Constant.Color.Blue) && zone.is(Constant.Zone.Hand))
if(CardUtil.getColors(c).contains(Constant.Color.Blue) && zone.is(Constant.Zone.Hand) &&
!c.equals(card))
{
AllZone.GameAction.removeFromGame(c);
String player = card.getController();

View File

@@ -505,8 +505,8 @@ public class CardFactoryUtil
{
if(choices.contains(card))
{
AllZone.getZone(card).remove(card);
AllZone.GameAction.moveToGraveyard(card);
//AllZone.getZone(card).remove(card);
AllZone.GameAction.sacrifice(card);
stop();
}
}
@@ -3025,7 +3025,6 @@ public class CardFactoryUtil
return count;
}
public static CardList getFastbonds(String player)
{
CardList list = new CardList(AllZone.getZone(Constant.Zone.Play, player).getCards());
@@ -3033,6 +3032,28 @@ public class CardFactoryUtil
return list;
}
//total cost to pay for an attacker c, cards like Propaganda, Ghostly Prison, Collective Restraint, ...
public static String getPropagandaCost(Card c)
{
String s = "";
PlayerZone play = AllZone.getZone(Constant.Zone.Play, AllZone.GameAction.getOpponent(c.getController()));
CardList list = new CardList(play.getCards());
list = list.filter(new CardListFilter()
{
public boolean addCard(Card c)
{
return c.getName().equals("Propaganda") || c.getName().equals("Windborn Muse") || c.getName().equals("Ghostly Prison");
}
});
int cost = list.size() * 2;
s = Integer.toString(cost);
return s;
}
//do card1 and card2 share any colors?
public static boolean sharesColorWith(Card card1, Card card2)
{

View File

@@ -19368,7 +19368,7 @@ public class CardFactory_Creatures {
}//*************** END ************ END **************************
//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Lockjaw Snapper"))
{
@@ -19408,8 +19408,34 @@ public class CardFactory_Creatures {
}
};//command
card.addDestroyCommand(destroy);
}//*************** START *********** START **************************
}//*************** END ************ END **************************
//*************** START *********** START **************************
else if (cardName.equals("Arctic Nishoba"))
{
final Ability ability = new Ability(card, "0")
{
public void resolve()
{
int lifeGain = card.getCounters(Counters.AGE) * 2;
AllZone.GameAction.getPlayerLife(card.getController()).addLife(lifeGain);
}
};
Command destroy = new Command()
{
private static final long serialVersionUID = 1863551466234257411L;
public void execute()
{
ability.setStackDescription(card.getName()+ " - gain 2 life for each age counter on it.");
AllZone.Stack.add(ability);
}
};//command
card.addDestroyCommand(destroy);
}//*************** END ************ END **************************
// Cards with Cycling abilities
// -1 means keyword "Cycling" not found
if (shouldCycle(card) != -1)

View File

@@ -145,7 +145,7 @@ public class Combat
public void addAttackingDamage(int n) {attackingDamage += n;}
public int getAttackingDamage() {return attackingDamage;}
public void addAttacker(Card c) {map.put(c, new CardList()); declaredAttackers++;}
public void addAttacker(Card c) {map.put(c, new CardList()); declaredAttackers++; }
public void resetAttackers() {map.clear();}
public Card[] getAttackers()
{

View File

@@ -17,11 +17,6 @@ public class CombatUtil
&& blocker.getKeyword().contains("This creature can block creatures with shadow as though they didn't have shadow."))
return false;
/*
if(attacker.getKeyword().contains("Shadow"))
return blocker.getKeyword().contains("Shadow") ||
blocker.getKeyword().contains("This creature can block creatures with shadow as though they didn't have shadow.");
*/
if (attacker.getKeyword().contains("Shadow") && !blocker.getKeyword().contains("Shadow")
&& !blocker.getKeyword().contains("This creature can block creatures with shadow as though they didn't have shadow.") )
return false;
@@ -194,13 +189,14 @@ public class CombatUtil
public static boolean canAttack(Card c)
{
if (isPeaceKeeperInPlay())
return false;
boolean moatPrevented = false;
if (isMoatInPlay() || isMagusMoatInPlay())
{
if (!c.getKeyword().contains("Flying"))
{
moatPrevented = true;
}
}
PlayerZone play = AllZone.getZone(Constant.Zone.Play,AllZone.GameAction.getOpponent(c.getController()));
@@ -661,6 +657,16 @@ public class CombatUtil
return false;
}
public static boolean isPeaceKeeperInPlay()
{
CardList all = new CardList();
all.addAll(AllZone.Human_Play.getCards());
all.addAll(AllZone.Computer_Play.getCards());
all = all.getName("Peacekeeper");
return all.size() > 0;
}
public static boolean isMoatInPlay()
{
CardList all = new CardList();
@@ -687,6 +693,68 @@ public class CombatUtil
return false;
}
public static boolean checkPropagandaEffects(Card c)
{
if (CardFactoryUtil.getPropagandaCost(c).equals("0"))
return true;
final Card crd = c;
final boolean[] canAttack = new boolean[1];
canAttack[0] = false;
//if (AllZone.Phase.getPhase().equals(Constant.Phase.Combat_Declare_Attackers))
if (AllZone.Phase.getPhase().equals("Declare Blockers") ||
AllZone.Phase.getPhase().equals(Constant.Phase.Combat_Declare_Attackers_InstantAbility))
{
//if (!c.getCreatureAttackedThisTurn())
//{
String cost = CardFactoryUtil.getPropagandaCost(c);
if (!cost.equals("0"))
{
final Ability ability = new Ability(c, cost)
{
public void resolve()
{
canAttack[0] = true;
}
};
final Command unpaidCommand = new Command() {
private static final long serialVersionUID = -6483405139208343935L;
public void execute() {
//AllZone.GameAction.sacrifice(c);
canAttack[0] = false;
AllZone.Combat.removeFromCombat(crd);
crd.untap();
}
};
final Command paidCommand = new Command() {
private static final long serialVersionUID = -8303368287601871955L;
public void execute() {
canAttack[0] = true;
}
};
if (c.getController().equals(Constant.Player.Human)) {
AllZone.InputControl.setInput(new Input_PayManaCost_Ability("Propaganda "+ c +"\r\n", ability.getManaCost(), paidCommand, unpaidCommand));
}
else //computer
{
if (ComputerUtil.canPayCost(ability))
ComputerUtil.playNoStack(ability);
else
canAttack[0] = false;
}
}
}
//c.setCreatureAttackedThisTurn(true);
//}
return canAttack[0];
}
public static void checkDeclareAttackers(Card c) //this method checks triggered effects of attacking creatures, right before defending player declares blockers
{
//human does not have an "attackers_instantAbility" phase during his turn (yet), so triggers will happen at the beginning of declare blockers

View File

@@ -4108,9 +4108,11 @@ public class GameActionUtil
{
if (c.getKeyword().contains("Whenever this creature deals damage to a player, that player gets a poison counter."))
playerCombatDamage_PoisonCounter(c);
playerCombatDamage_PoisonCounter(c, 1);
if (c.getName().equals("Hypnotic Specter"))
if (c.getName().equals("Marsh Viper"))
playerCombatDamage_PoisonCounter(c, 2);
else if (c.getName().equals("Hypnotic Specter"))
playerCombatDamage_Hypnotic_Specter(c);
else if (c.getName().equals("Dimir Cutpurse"))
playerCombatDamage_Dimir_Cutpurse(c);
@@ -4207,15 +4209,15 @@ public class GameActionUtil
}
*/
private static void playerCombatDamage_PoisonCounter(Card c)
private static void playerCombatDamage_PoisonCounter(Card c, int n)
{
final String player = c.getController();
final String opponent = AllZone.GameAction.getOpponent(player);
if (opponent.equals(Constant.Player.Human))
AllZone.Human_PoisonCounter.addPoisonCounters(1);
AllZone.Human_PoisonCounter.addPoisonCounters(n);
else
AllZone.Computer_PoisonCounter.addPoisonCounters(1);
AllZone.Computer_PoisonCounter.addPoisonCounters(n);
}
private static void playerCombatDamage_Oros(Card c)
@@ -5134,6 +5136,7 @@ public class GameActionUtil
private static void upkeep_AEther_Vial()
{
final String player = AllZone.Phase.getActivePlayer();

View File

@@ -89,10 +89,12 @@ import java.util.*;
CardList list = new CardList();
list.addAll(AllZone.Combat.getAttackers());
list.addAll(AllZone.pwCombat.getAttackers());
for (Card c : list)
CombatUtil.checkPropagandaEffects(c);
for (Card c : list)
{
CombatUtil.checkDeclareAttackers(c);
}
return new Input_Attack_Instant();
}
@@ -296,6 +298,10 @@ import java.util.*;
CardList list = new CardList();
list.addAll(AllZone.Combat.getAttackers());
list.addAll(AllZone.pwCombat.getAttackers());
for (Card c : list)
{
CombatUtil.checkPropagandaEffects(c);
}
for (Card c : list)
{
CombatUtil.checkDeclareAttackers(c);

View File

@@ -17,6 +17,7 @@ public void showMessage()
Card c = creats.get(i);
if (CombatUtil.canAttack(c) && c.getKeyword().contains("This card attacks each turn if able."))
{
AllZone.Combat.addAttacker(c);
if (!c.getKeyword().contains("Vigilance"))
c.tap();
@@ -62,15 +63,15 @@ public void showMessage()
CombatUtil.canAttack(card)
)
{
if(! card.getKeyword().contains("Vigilance"))
{
card.tap();
//otherwise cards stay untapped, not sure why this is needed but it works
AllZone.Human_Play.updateObservers();
}
AllZone.Combat.addAttacker(card);
//for Castle Raptors, since it gets a bonus if untapped
for (String effect : AllZone.StateBasedEffects.getStateBasedMap().keySet() ) {
Command com = GameActionUtil.commands.get(effect);

View File

@@ -65,9 +65,11 @@ public class Input_PayManaCost_Ability extends Input
//tappedLand.clear();
AllZone.ManaPool.paid();
//Command MUST BE AFTER, for Urborg Syphon-Mage - tap, mana, discard abilit
stopSetNext(new ComputerAI_StackNotEmpty());
//Command MUST BE AFTER, for Urborg Syphon-Mage - tap, mana, discard ability
//does it really have to be after?
paidCommand.execute();
stopSetNext(new ComputerAI_StackNotEmpty());
//paidCommand.execute();
}
}