- Added Debt of Loyalty, Matopi Golem, Skeleton Scavengers, and Soldevi Sentry

This commit is contained in:
swordshine
2013-12-28 05:08:39 +00:00
parent 2de5beb6d1
commit 58e529097f
22 changed files with 200 additions and 29 deletions

View File

@@ -1359,7 +1359,7 @@ public class ComputerUtil {
}
// already regenerated
if (c.getShield() > 0) {
if (!c.getShield().isEmpty()) {
continue;
}
@@ -1411,7 +1411,7 @@ public class ComputerUtil {
}
// already regenerated
if (c.getShield() > 0) {
if (!c.getShield().isEmpty()) {
continue;
}

View File

@@ -1884,7 +1884,7 @@ public class ComputerUtilCombat {
final boolean noPrevention) {
final int killDamage = ComputerUtilCombat.getDamageToKill(c);
if (c.hasKeyword("Indestructible") || (c.getShield() > 0)) {
if (c.hasKeyword("Indestructible") || !c.getShield().isEmpty()) {
if (!(source.hasKeyword("Wither") || source.hasKeyword("Infect"))) {
return maxDamage + 1;
}

View File

@@ -765,7 +765,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
CardLists.sortByEvaluateCreature(combatants);
for (final Card c : combatants) {
if (c.getShield() == 0 && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c, combat) && c.getOwner() == ai && !c.isToken()) {
if (c.getShield().isEmpty() && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c, combat) && c.getOwner() == ai && !c.isToken()) {
sa.getTargets().add(c);
return true;
}

View File

@@ -104,7 +104,7 @@ public class DestroyAi extends SpellAbilityAi {
list = CardLists.filter(list, new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
return ((c.getShield() == 0) && !ComputerUtil.canRegenerate(ai, c));
return (c.getShield().isEmpty() && !ComputerUtil.canRegenerate(ai, c));
}
});
}
@@ -201,7 +201,7 @@ public class DestroyAi extends SpellAbilityAi {
preferred = CardLists.filter(preferred, new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
return c.getShield() == 0;
return c.getShield().isEmpty();
}
});
}

View File

@@ -132,7 +132,7 @@ public abstract class PumpAiBase extends SpellAbilityAi {
return false;
}
} else if (keyword.endsWith("CARDNAME can't be regenerated.")) {
if (card.getShield() > 0) {
if (!card.getShield().isEmpty()) {
return true;
}
if (card.hasKeyword("If CARDNAME would be destroyed, regenerate it.") && combat != null

View File

@@ -103,7 +103,7 @@ public class RegenerateAi extends SpellAbilityAi {
boolean flag = false;
for (final Card c : list) {
if (c.getShield() == 0) {
if (c.getShield().isEmpty()) {
flag |= ComputerUtilCombat.combatantWouldBeDestroyed(ai, c, combat);
}
}
@@ -132,7 +132,7 @@ public class RegenerateAi extends SpellAbilityAi {
final List<Card> threatenedTargets = new ArrayList<Card>();
for (final Card c : targetables) {
if (objects.contains(c) && (c.getShield() == 0)) {
if (objects.contains(c) && c.getShield().isEmpty()) {
threatenedTargets.add(c);
}
}
@@ -148,7 +148,7 @@ public class RegenerateAi extends SpellAbilityAi {
CardLists.sortByEvaluateCreature(combatants);
for (final Card c : combatants) {
if ((c.getShield() == 0) && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c, combat)) {
if (c.getShield().isEmpty() && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c, combat)) {
sa.getTargets().add(c);
chance = true;
break;
@@ -204,7 +204,7 @@ public class RegenerateAi extends SpellAbilityAi {
if (game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS)) {
Combat combat = game.getCombat();
for (final Card c : combatants) {
if ((c.getShield() == 0) && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c, combat)) {
if (c.getShield().isEmpty() && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c, combat)) {
sa.getTargets().add(c);
return true;
}
@@ -217,7 +217,7 @@ public class RegenerateAi extends SpellAbilityAi {
// choose my best X without regen
if (CardLists.getNotType(compTargetables, "Creature").isEmpty()) {
for (final Card c : combatants) {
if (c.getShield() == 0) {
if (c.getShield().isEmpty()) {
sa.getTargets().add(c);
return true;
}
@@ -227,7 +227,7 @@ public class RegenerateAi extends SpellAbilityAi {
} else {
CardLists.sortByCmcDesc(compTargetables);
for (final Card c : compTargetables) {
if (c.getShield() == 0) {
if (c.getShield().isEmpty()) {
sa.getTargets().add(c);
return true;
}

View File

@@ -61,7 +61,7 @@ public class RegenerateAllAi extends SpellAbilityAi {
final List<GameObject> objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa);
for (final Card c : list) {
if (objects.contains(c) && c.getShield() == 0) {
if (objects.contains(c) && c.getShield().isEmpty()) {
numSaved++;
}
}
@@ -70,7 +70,7 @@ public class RegenerateAllAi extends SpellAbilityAi {
final List<Card> combatants = CardLists.filter(list, CardPredicates.Presets.CREATURES);
final Combat combat = game.getCombat();
for (final Card c : combatants) {
if (c.getShield() == 0 && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c, combat)) {
if (c.getShield().isEmpty() && ComputerUtilCombat.combatantWouldBeDestroyed(ai, c, combat)) {
numSaved++;
}
}

View File

@@ -1244,8 +1244,8 @@ public class GameAction {
}
if (c.canBeShielded() && (!c.isCreature() || c.getNetDefense() > 0)
&& (c.getShield() > 0 || c.hasKeyword("If CARDNAME would be destroyed, regenerate it."))) {
c.subtractShield();
&& (!c.getShield().isEmpty() || c.hasKeyword("If CARDNAME would be destroyed, regenerate it."))) {
c.subtractShield(c.getController().getController().chooseRegenerationShield(c));
c.setDamage(0);
c.tap();
c.addRegeneratedThisTurn();

View File

@@ -7,6 +7,7 @@ import forge.game.Game;
import forge.game.ability.SpellAbilityEffect;
import forge.game.card.Card;
import forge.game.card.CardLists;
import forge.game.card.CardShields;
import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
@@ -41,7 +42,7 @@ public class RegenerateAllEffect extends SpellAbilityEffect {
};
if (c.isInPlay()) {
c.addShield();
c.addShield(new CardShields(sa, null));
game.getEndOfTurn().addUntil(untilEOT);
}
}

View File

@@ -5,8 +5,12 @@ import java.util.List;
import forge.Command;
import forge.game.Game;
import forge.game.ability.AbilityFactory;
import forge.game.ability.AbilityUtils;
import forge.game.ability.SpellAbilityEffect;
import forge.game.card.Card;
import forge.game.card.CardShields;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetRestrictions;
@@ -46,6 +50,7 @@ public class RegenerateEffect extends SpellAbilityEffect {
public void resolve(SpellAbility sa) {
final TargetRestrictions tgt = sa.getTargetRestrictions();
final Game game = sa.getActivatingPlayer().getGame();
final Card sourceCard = sa.getSourceCard();
for (final Card tgtC : getTargetCards(sa)) {
final Command untilEOT = new Command() {
@@ -57,8 +62,26 @@ public class RegenerateEffect extends SpellAbilityEffect {
}
};
if (tgtC.isInPlay() && ((tgt == null) || tgtC.canBeTargetedBy(sa))) {
tgtC.addShield();
if (tgtC.isInPlay() && (tgt == null || tgt.canTgtPlayer() || tgtC.canBeTargetedBy(sa))) {
SpellAbility triggerSA = null;
if (sa.hasParam("RegenerationTrigger")) {
String abString = sa.getSourceCard().getSVar(sa.getParam("RegenerationTrigger"));
if (sa.hasParam("ReplacePlayerName")) { // Soldevi Sentry
String def = sa.getParam("ReplacePlayerName");
List<Player> replaced = AbilityUtils.getDefinedPlayers(sourceCard, def, sa);
abString = abString.replace(def, replaced.isEmpty() ? "" : replaced.get(0).getName());
} else if (sa.hasParam("ReplaceCardUID")) { // Debt of Loyalty
String def = sa.getParam("ReplaceCardUID");
List<Card> replaced = AbilityUtils.getDefinedCards(sourceCard, def, sa);
abString = abString.replace(def, replaced.isEmpty() ? "" : Integer.toString(replaced.get(0).getUniqueNumber()));
}
triggerSA = AbilityFactory.getAbility(abString, sourceCard);
triggerSA.setActivatingPlayer(sa.getActivatingPlayer());
triggerSA.setTrigger(true);
triggerSA.setSourceCard(sourceCard);
}
CardShields shield = new CardShields(sa, triggerSA);
tgtC.addShield(shield);
game.getEndOfTurn().addUntil(untilEOT);
}
}

View File

@@ -198,7 +198,7 @@ public class Card extends GameEntity implements Comparable<Card> {
private int damage;
// regeneration
private int nShield;
private List<CardShields> nShield = new ArrayList<CardShields>();
private int regeneratedThisTurn = 0;
private int turnInZone;
@@ -2686,7 +2686,7 @@ public class Card extends GameEntity implements Comparable<Card> {
*
* @return a int.
*/
public final int getShield() {
public final List<CardShields> getShield() {
return this.nShield;
}
@@ -2695,8 +2695,8 @@ public class Card extends GameEntity implements Comparable<Card> {
* addShield.
* </p>
*/
public final void addShield() {
this.nShield++;
public final void addShield(final CardShields shield) {
this.nShield.add(shield);
}
/**
@@ -2704,8 +2704,11 @@ public class Card extends GameEntity implements Comparable<Card> {
* subtractShield.
* </p>
*/
public final void subtractShield() {
this.nShield--;
public final void subtractShield(CardShields shield) {
if (shield != null && shield.hasTrigger()) {
this.getGame().getStack().addSimultaneousStackEntry(shield.getTriggerSA());
}
this.nShield.remove(shield);
}
/**
@@ -2740,7 +2743,7 @@ public class Card extends GameEntity implements Comparable<Card> {
* </p>
*/
public final void resetShield() {
this.nShield = 0;
this.nShield.clear();;
}
/**

View File

@@ -0,0 +1,79 @@
/*
* Forge: Play Magic: the Gathering.
* Copyright (C) 2011 Forge Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package forge.game.card;
import forge.game.spellability.SpellAbility;
/**
* <p>
* Card_Shields class.
* </p>
*
* @author Forge
* @version $Id: CardShields.java 23786 2013-11-24 06:59:42Z Max mtg $
*/
public class CardShields {
// restore the regeneration shields
private final SpellAbility sourceSA;
private final SpellAbility triggerSA;
/**
* Instantiates a new CardShields.
*
* @param sourceSA
* a SpellAbility
*/
public CardShields(final SpellAbility sourceSA, final SpellAbility triggerSA) {
this.sourceSA = sourceSA;
this.triggerSA = triggerSA;
}
/**
*
* getSourceSA.
*
* @return sourceSA
*/
public final SpellAbility getSourceSA() {
return this.sourceSA;
}
/**
*
* getTriggerSA.
*
* @return triggerSA
*/
public final SpellAbility getTriggerSA() {
return this.triggerSA;
}
public final boolean hasTrigger() {
return this.triggerSA != null;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
String suffix = this.triggerSA != null ? " - " + triggerSA.getDescription() : "";
return this.sourceSA.getSourceCard().getName() + suffix;
}
}

View File

@@ -19,6 +19,7 @@ import forge.game.GameEntity;
import forge.game.GameObject;
import forge.game.GameType;
import forge.game.card.Card;
import forge.game.card.CardShields;
import forge.game.card.CounterType;
import forge.game.combat.Combat;
import forge.game.cost.Cost;
@@ -195,7 +196,8 @@ public abstract class PlayerController {
public abstract boolean confirmPayment(CostPart costPart, String string);
public abstract ReplacementEffect chooseSingleReplacementEffect(String prompt, List<ReplacementEffect> possibleReplacers, HashMap<String, Object> runParams);
public abstract String chooseProtectionType(String string, SpellAbility sa, List<String> choices);
public abstract CardShields chooseRegenerationShield(Card c);
// these 4 need some refining.
public abstract boolean payCostToPreventEffect(Cost cost, SpellAbility sa, boolean alreadyPaid, List<Player> allPayers);
public abstract void orderAndPlaySimultaneousSa(List<SpellAbility> activePlayerSAs);
@@ -210,4 +212,6 @@ public abstract class PlayerController {
// These 2 are for AI
public List<Card> cheatShuffle(List<Card> list) { return list; }
public Collection<? extends PaperCard> complainCardsCantPlayWell(Deck myDeck) { return null; }
}

View File

@@ -38,6 +38,7 @@ import forge.game.ability.ApiType;
import forge.game.card.Card;
import forge.game.card.CardLists;
import forge.game.card.CardPredicates;
import forge.game.card.CardShields;
import forge.game.card.CounterType;
import forge.game.combat.Combat;
import forge.game.cost.Cost;
@@ -688,4 +689,9 @@ public class PlayerControllerAi extends PlayerController {
return brains.cheatShuffle(list);
}
@Override
public CardShields chooseRegenerationShield(Card c) {
return Iterables.getFirst(c.getShield(), null);
}
}

View File

@@ -393,7 +393,7 @@ public class CardDetailPanel extends FPanel {
}
// Regeneration Shields
final int regenShields = card.getShield();
final int regenShields = card.getShield().size();
if (regenShields > 0) {
if (area.length() != 0) {
area.append("\n");

View File

@@ -8,6 +8,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.KeyStroke;
@@ -38,6 +39,7 @@ import forge.game.GameObject;
import forge.game.GameType;
import forge.game.ability.effects.CharmEffect;
import forge.game.card.Card;
import forge.game.card.CardShields;
import forge.game.card.CounterType;
import forge.game.combat.Combat;
import forge.game.cost.Cost;
@@ -1066,4 +1068,12 @@ public class PlayerControllerHuman extends PlayerController {
GuiChoose.one(message, anteedThings);
}
@Override
public CardShields chooseRegenerationShield(Card c) {
if (c.getShield().size() < 2) {
return Iterables.getFirst(c.getShield(), null);
}
return GuiChoose.one("Choose a regeneration shield:", c.getShield());
}
}

View File

@@ -28,6 +28,7 @@ import forge.game.GameObject;
import forge.game.GameType;
import forge.game.ability.AbilityUtils;
import forge.game.card.Card;
import forge.game.card.CardShields;
import forge.game.card.CounterType;
import forge.game.combat.Combat;
import forge.game.combat.CombatUtil;
@@ -544,4 +545,9 @@ public class PlayerControllerForTests extends PlayerController {
public void revealAnte(String message, Multimap<Player, PaperCard> removedAnteCards) {
// test this!
}
@Override
public CardShields chooseRegenerationShield(Card c) {
return Iterables.getFirst(c.getShield(), null);
}
}