mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 04:08:01 +00:00
- Added Debt of Loyalty, Matopi Golem, Skeleton Scavengers, and Soldevi Sentry
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
79
forge-gui/src/main/java/forge/game/card/CardShields.java
Normal file
79
forge-gui/src/main/java/forge/game/card/CardShields.java
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user