mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 20:28:00 +00:00
Merge branch 'regeneration' into 'master'
Regeneration See merge request core-developers/forge!168
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
package forge.ai;
|
package forge.ai;
|
||||||
|
|
||||||
import com.esotericsoftware.minlog.Log;
|
//import com.esotericsoftware.minlog.Log;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
@@ -398,7 +398,7 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
if (StringUtils.isBlank(chosen) && !validTypes.isEmpty())
|
if (StringUtils.isBlank(chosen) && !validTypes.isEmpty())
|
||||||
{
|
{
|
||||||
chosen = validTypes.get(0);
|
chosen = validTypes.get(0);
|
||||||
Log.warn("AI has no idea how to choose " + kindOfType +", defaulting to 1st element: chosen");
|
//Log.warn("AI has no idea how to choose " + kindOfType +", defaulting to 1st element: chosen");
|
||||||
}
|
}
|
||||||
game.getAction().nofityOfValue(sa, player, chosen, player);
|
game.getAction().nofityOfValue(sa, player, chosen, player);
|
||||||
return chosen;
|
return chosen;
|
||||||
@@ -866,11 +866,6 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
return brains.getBooleanProperty(AiProps.CHEAT_WITH_MANA_ON_SHUFFLE) ? brains.cheatShuffle(list) : list;
|
return brains.getBooleanProperty(AiProps.CHEAT_WITH_MANA_ON_SHUFFLE) ? brains.cheatShuffle(list) : list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public CardShields chooseRegenerationShield(Card c) {
|
|
||||||
return Iterables.getFirst(c.getShields(), null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<PaperCard> chooseCardsYouWonToAddToDeck(List<PaperCard> losses) {
|
public List<PaperCard> chooseCardsYouWonToAddToDeck(List<PaperCard> losses) {
|
||||||
// TODO AI takes all by default
|
// TODO AI takes all by default
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ public enum SpellApiToAi {
|
|||||||
.put(ApiType.RearrangeTopOfLibrary, RearrangeTopOfLibraryAi.class)
|
.put(ApiType.RearrangeTopOfLibrary, RearrangeTopOfLibraryAi.class)
|
||||||
.put(ApiType.Regenerate, RegenerateAi.class)
|
.put(ApiType.Regenerate, RegenerateAi.class)
|
||||||
.put(ApiType.RegenerateAll, RegenerateAllAi.class)
|
.put(ApiType.RegenerateAll, RegenerateAllAi.class)
|
||||||
|
.put(ApiType.Regeneration, AlwaysPlayAi.class)
|
||||||
.put(ApiType.RemoveCounter, CountersRemoveAi.class)
|
.put(ApiType.RemoveCounter, CountersRemoveAi.class)
|
||||||
.put(ApiType.RemoveCounterAll, CannotPlayAi.class)
|
.put(ApiType.RemoveCounterAll, CannotPlayAi.class)
|
||||||
.put(ApiType.RemoveFromCombat, RemoveFromCombatAi.class)
|
.put(ApiType.RemoveFromCombat, RemoveFromCombatAi.class)
|
||||||
|
|||||||
@@ -1402,26 +1402,13 @@ public class GameAction {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c.canBeShielded() && (!c.isCreature() || c.getNetToughness() > 0)
|
return destroy(c, sa, true);
|
||||||
&& (c.getShieldCount() > 0 || c.hasKeyword("If CARDNAME would be destroyed, regenerate it."))) {
|
}
|
||||||
c.subtractShield(c.getController().getController().chooseRegenerationShield(c));
|
public final boolean destroyNoRegeneration(final Card c, final SpellAbility sa) {
|
||||||
c.setDamage(0);
|
return destroy(c, sa, false);
|
||||||
c.setHasBeenDealtDeathtouchDamage(false);
|
|
||||||
c.tap();
|
|
||||||
c.addRegeneratedThisTurn();
|
|
||||||
if (game.getCombat() != null) {
|
|
||||||
game.getCombat().removeFromCombat(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Play the Regen sound
|
|
||||||
game.fireEvent(new GameEventCardRegenerated());
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return destroyNoRegeneration(c, sa);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean destroyNoRegeneration(final Card c, final SpellAbility sa) {
|
public final boolean destroy(final Card c, final SpellAbility sa, final boolean regenerate) {
|
||||||
Player activator = null;
|
Player activator = null;
|
||||||
if (!c.canBeDestroyed()) {
|
if (!c.canBeDestroyed()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -1433,6 +1420,7 @@ public class GameAction {
|
|||||||
repRunParams.put("Source", sa);
|
repRunParams.put("Source", sa);
|
||||||
repRunParams.put("Card", c);
|
repRunParams.put("Card", c);
|
||||||
repRunParams.put("Affected", c);
|
repRunParams.put("Affected", c);
|
||||||
|
repRunParams.put("Regeneration", regenerate);
|
||||||
|
|
||||||
if (game.getReplacementHandler().run(repRunParams) != ReplacementResult.NotReplaced) {
|
if (game.getReplacementHandler().run(repRunParams) != ReplacementResult.NotReplaced) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ public enum ApiType {
|
|||||||
RearrangeTopOfLibrary (RearrangeTopOfLibraryEffect.class),
|
RearrangeTopOfLibrary (RearrangeTopOfLibraryEffect.class),
|
||||||
Regenerate (RegenerateEffect.class),
|
Regenerate (RegenerateEffect.class),
|
||||||
RegenerateAll (RegenerateAllEffect.class),
|
RegenerateAll (RegenerateAllEffect.class),
|
||||||
|
Regeneration (RegenerationEffect.class),
|
||||||
RemoveCounter (CountersRemoveEffect.class),
|
RemoveCounter (CountersRemoveEffect.class),
|
||||||
RemoveCounterAll (CountersRemoveAllEffect.class),
|
RemoveCounterAll (CountersRemoveAllEffect.class),
|
||||||
RemoveFromCombat (RemoveFromCombatEffect.class),
|
RemoveFromCombat (RemoveFromCombatEffect.class),
|
||||||
|
|||||||
@@ -292,9 +292,16 @@ public abstract class SpellAbilityEffect {
|
|||||||
|
|
||||||
protected static void addForgetOnMovedTrigger(final Card card, final String zone) {
|
protected static void addForgetOnMovedTrigger(final Card card, final String zone) {
|
||||||
String trig = "Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ " + zone + " | Destination$ Any | TriggerZones$ Command | Static$ True";
|
String trig = "Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ " + zone + " | Destination$ Any | TriggerZones$ Command | Static$ True";
|
||||||
String effect = "DB$ Pump | ForgetObjects$ TriggeredCard";
|
String forgetEffect = "DB$ Pump | ForgetObjects$ TriggeredCard";
|
||||||
|
String exileEffect = "DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile"
|
||||||
|
+ " | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ EQ0";
|
||||||
|
|
||||||
|
SpellAbility saForget = AbilityFactory.getAbility(forgetEffect, card);
|
||||||
|
AbilitySub saExile = (AbilitySub) AbilityFactory.getAbility(exileEffect, card);
|
||||||
|
saForget.setSubAbility(saExile);
|
||||||
|
|
||||||
final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig, card, true);
|
final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig, card, true);
|
||||||
parsedTrigger.setOverridingAbility(AbilityFactory.getAbility(effect, card));
|
parsedTrigger.setOverridingAbility(saForget);
|
||||||
final Trigger addedTrigger = card.addTrigger(parsedTrigger);
|
final Trigger addedTrigger = card.addTrigger(parsedTrigger);
|
||||||
addedTrigger.setIntrinsic(true);
|
addedTrigger.setIntrinsic(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,27 @@
|
|||||||
package forge.game.ability.effects;
|
package forge.game.ability.effects;
|
||||||
|
|
||||||
import forge.GameCommand;
|
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.ability.SpellAbilityEffect;
|
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardCollectionView;
|
import forge.game.card.CardCollectionView;
|
||||||
import forge.game.card.CardLists;
|
import forge.game.card.CardLists;
|
||||||
import forge.game.card.CardShields;
|
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
|
|
||||||
public class RegenerateAllEffect extends SpellAbilityEffect {
|
public class RegenerateAllEffect extends RegenerateBaseEffect {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see forge.game.ability.SpellAbilityEffect#getStackDescription(forge.game.spellability.SpellAbility)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected String getStackDescription(SpellAbility sa) {
|
protected String getStackDescription(SpellAbility sa) {
|
||||||
return "Regenerate all valid cards.";
|
return "Regenerate all valid cards.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see forge.game.ability.SpellAbilityEffect#resolve(forge.game.spellability.SpellAbility)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void resolve(SpellAbility sa) {
|
public void resolve(SpellAbility sa) {
|
||||||
final Card hostCard = sa.getHostCard();
|
final Card hostCard = sa.getHostCard();
|
||||||
@@ -30,21 +35,8 @@ public class RegenerateAllEffect extends SpellAbilityEffect {
|
|||||||
CardCollectionView list = game.getCardsIn(ZoneType.Battlefield);
|
CardCollectionView list = game.getCardsIn(ZoneType.Battlefield);
|
||||||
list = CardLists.getValidCards(list, valid.split(","), hostCard.getController(), hostCard, sa);
|
list = CardLists.getValidCards(list, valid.split(","), hostCard.getController(), hostCard, sa);
|
||||||
|
|
||||||
for (final Card c : list) {
|
// create Effect for Regeneration
|
||||||
final GameCommand untilEOT = new GameCommand() {
|
createRengenerationEffect(sa, list);
|
||||||
private static final long serialVersionUID = 259368227093961103L;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
c.resetShield();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (c.isInPlay()) {
|
|
||||||
c.addShield(new CardShields(sa, null));
|
|
||||||
game.getEndOfTurn().addUntil(untilEOT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // regenerateAllResolve
|
} // regenerateAllResolve
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
package forge.game.ability.effects;
|
||||||
|
|
||||||
|
import forge.GameCommand;
|
||||||
|
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.replacement.ReplacementEffect;
|
||||||
|
import forge.game.replacement.ReplacementHandler;
|
||||||
|
import forge.game.spellability.AbilitySub;
|
||||||
|
import forge.game.spellability.SpellAbility;
|
||||||
|
import forge.game.trigger.Trigger;
|
||||||
|
import forge.game.trigger.TriggerHandler;
|
||||||
|
import forge.game.trigger.TriggerType;
|
||||||
|
import forge.game.zone.ZoneType;
|
||||||
|
|
||||||
|
public abstract class RegenerateBaseEffect extends SpellAbilityEffect {
|
||||||
|
|
||||||
|
public void createRengenerationEffect(SpellAbility sa, final Iterable<Card> list) {
|
||||||
|
final Card hostCard = sa.getHostCard();
|
||||||
|
final Game game = hostCard.getGame();
|
||||||
|
|
||||||
|
// create Effect for Regeneration
|
||||||
|
Card eff = createEffect(
|
||||||
|
hostCard, sa.getActivatingPlayer(), hostCard.getName() + "'s Regeneration", hostCard.getImageKey());
|
||||||
|
|
||||||
|
eff.addRemembered(list);
|
||||||
|
addForgetOnMovedTrigger(eff, "Battlefield");
|
||||||
|
|
||||||
|
// build ReplacementEffect
|
||||||
|
String repeffstr = "Event$ Destroy | ActiveZones$ Command | ValidCard$ Card.IsRemembered | Regeneration$ True"
|
||||||
|
+ " | Description$ Regeneration (if creature would be destroyed, regenerate it instead)";
|
||||||
|
|
||||||
|
String effect = "DB$ Regeneration | Defined$ ReplacedCard";
|
||||||
|
String exileEff = "DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile"
|
||||||
|
+ " | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ EQ0";
|
||||||
|
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, eff, true);
|
||||||
|
|
||||||
|
SpellAbility saReg = AbilityFactory.getAbility(effect, eff);
|
||||||
|
AbilitySub saExile = (AbilitySub)AbilityFactory.getAbility(exileEff, eff);
|
||||||
|
|
||||||
|
saReg.setSubAbility(saExile);
|
||||||
|
re.setOverridingAbility(saReg);
|
||||||
|
eff.addReplacementEffect(re);
|
||||||
|
|
||||||
|
// add extra Remembered
|
||||||
|
if (sa.hasParam("RememberObjects")) {
|
||||||
|
eff.addRemembered(AbilityUtils.getDefinedObjects(hostCard, sa.getParam("RememberObjects"), sa));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sa.hasParam("RegenerationTrigger")) {
|
||||||
|
final String str = sa.getSVar(sa.getParam("RegenerationTrigger"));
|
||||||
|
|
||||||
|
SpellAbility trigSA = AbilityFactory.getAbility(str, eff);
|
||||||
|
|
||||||
|
final String trigStr = "Mode$ Regenerated | ValidCause$ Effect.Self | TriggerZones$ Command "
|
||||||
|
+ " | TriggerDescription$ " + trigSA.getDescription();
|
||||||
|
final Trigger trigger = TriggerHandler.parseTrigger(trigStr, eff, true);
|
||||||
|
trigger.setOverridingAbility(trigSA);
|
||||||
|
eff.moveTrigger(trigger);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy text changes
|
||||||
|
if (sa.isIntrinsic()) {
|
||||||
|
eff.copyChangedTextFrom(hostCard);
|
||||||
|
}
|
||||||
|
|
||||||
|
eff.updateStateForView();
|
||||||
|
|
||||||
|
// add RegenEffect as Shield to the Affected Cards
|
||||||
|
for (final Card c : list) {
|
||||||
|
c.addShield(eff);
|
||||||
|
}
|
||||||
|
game.getTriggerHandler().suppressMode(TriggerType.ChangesZone);
|
||||||
|
game.getAction().moveTo(ZoneType.Command, eff, sa);
|
||||||
|
game.getTriggerHandler().clearSuppression(TriggerType.ChangesZone);
|
||||||
|
|
||||||
|
final GameCommand untilEOT = new GameCommand() {
|
||||||
|
private static final long serialVersionUID = 259368227093961103L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
game.getAction().exile(eff, null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
game.getEndOfTurn().addUntil(untilEOT);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,24 +1,16 @@
|
|||||||
package forge.game.ability.effects;
|
package forge.game.ability.effects;
|
||||||
|
|
||||||
import forge.GameCommand;
|
|
||||||
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.Card;
|
||||||
import forge.game.card.CardShields;
|
|
||||||
import forge.game.player.Player;
|
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.spellability.TargetRestrictions;
|
|
||||||
import forge.util.TextUtil;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class RegenerateEffect extends SpellAbilityEffect {
|
public class RegenerateEffect extends RegenerateBaseEffect {
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/*
|
||||||
* @see forge.card.abilityfactory.SpellEffect#getStackDescription(java.util.Map, forge.card.spellability.SpellAbility)
|
* (non-Javadoc)
|
||||||
|
* @see forge.game.ability.SpellAbilityEffect#getStackDescription(forge.game.spellability.SpellAbility)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected String getStackDescription(SpellAbility sa) {
|
protected String getStackDescription(SpellAbility sa) {
|
||||||
@@ -47,51 +39,14 @@ public class RegenerateEffect extends SpellAbilityEffect {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see forge.game.ability.SpellAbilityEffect#resolve(forge.game.spellability.SpellAbility)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void resolve(SpellAbility sa) {
|
public void resolve(SpellAbility sa) {
|
||||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
// create Effect for Regeneration
|
||||||
final Game game = sa.getActivatingPlayer().getGame();
|
createRengenerationEffect(sa, getTargetCards(sa));
|
||||||
final Card sourceCard = sa.getHostCard();
|
|
||||||
|
|
||||||
for (final Card tgtC : getTargetCards(sa)) {
|
|
||||||
final GameCommand untilEOT = new GameCommand() {
|
|
||||||
private static final long serialVersionUID = 1922050611313909200L;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
tgtC.resetShield();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (tgtC.isInPlay() && (tgt == null || tgt.canTgtPlayer() || tgtC.canBeTargetedBy(sa))) {
|
|
||||||
SpellAbility triggerSA = null;
|
|
||||||
if (sa.hasParam("RegenerationTrigger")) {
|
|
||||||
String abString = sa.getHostCard().getSVar(sa.getParam("RegenerationTrigger"));
|
|
||||||
if (sa.hasParam("ReplacePlayerName")) { // Soldevi Sentry
|
|
||||||
String def = sa.getParam("ReplacePlayerName");
|
|
||||||
List<Player> replaced = AbilityUtils.getDefinedPlayers(sourceCard, def, sa);
|
|
||||||
if(replaced.isEmpty())
|
|
||||||
abString = TextUtil.fastReplace(abString, def, "");
|
|
||||||
else
|
|
||||||
abString = TextUtil.fastReplace(abString, def, 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);
|
|
||||||
if(replaced.isEmpty())
|
|
||||||
abString = TextUtil.fastReplace(abString, def, "");
|
|
||||||
else
|
|
||||||
abString = TextUtil.fastReplace(abString, def, Integer.toString(replaced.get(0).getId()));
|
|
||||||
}
|
|
||||||
triggerSA = AbilityFactory.getAbility(abString, sourceCard);
|
|
||||||
triggerSA.setActivatingPlayer(sa.getActivatingPlayer());
|
|
||||||
triggerSA.setTrigger(true);
|
|
||||||
triggerSA.setHostCard(sourceCard);
|
|
||||||
}
|
|
||||||
CardShields shield = new CardShields(sa, triggerSA);
|
|
||||||
tgtC.addShield(shield);
|
|
||||||
game.getEndOfTurn().addUntil(untilEOT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // regenerateResolve
|
} // regenerateResolve
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package forge.game.ability.effects;
|
||||||
|
|
||||||
|
import forge.game.Game;
|
||||||
|
import forge.game.ability.SpellAbilityEffect;
|
||||||
|
import forge.game.card.Card;
|
||||||
|
import forge.game.event.GameEventCardRegenerated;
|
||||||
|
import forge.game.spellability.SpellAbility;
|
||||||
|
import forge.game.trigger.TriggerType;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
|
public class RegenerationEffect extends SpellAbilityEffect {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see forge.game.ability.SpellAbilityEffect#resolve(forge.game.spellability.SpellAbility)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void resolve(SpellAbility sa) {
|
||||||
|
final Card host = sa.getHostCard();
|
||||||
|
final Game game = host.getGame();
|
||||||
|
for (Card c : getTargetCards(sa)) {
|
||||||
|
if (!c.canBeShielded() || !c.isInPlay()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
c.setDamage(0);
|
||||||
|
c.setHasBeenDealtDeathtouchDamage(false);
|
||||||
|
c.tap();
|
||||||
|
c.addRegeneratedThisTurn();
|
||||||
|
|
||||||
|
if (game.getCombat() != null) {
|
||||||
|
game.getCombat().removeFromCombat(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Play the Regen sound
|
||||||
|
game.fireEvent(new GameEventCardRegenerated());
|
||||||
|
|
||||||
|
if (host.getType().hasStringType("Effect")) {
|
||||||
|
c.subtractShield(host);
|
||||||
|
host.removeRemembered(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run triggers
|
||||||
|
final Map<String, Object> runParams = Maps.newHashMap();
|
||||||
|
runParams.put("Card", c);
|
||||||
|
runParams.put("Cause", host);
|
||||||
|
game.getTriggerHandler().runTrigger(TriggerType.Regenerated, runParams, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -194,7 +194,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
private boolean hasBeenDealtDeathtouchDamage = false;
|
private boolean hasBeenDealtDeathtouchDamage = false;
|
||||||
|
|
||||||
// regeneration
|
// regeneration
|
||||||
private List<CardShields> shields = Lists.newArrayList();
|
private FCollection<Card> shields = new FCollection<>();
|
||||||
private int regeneratedThisTurn = 0;
|
private int regeneratedThisTurn = 0;
|
||||||
|
|
||||||
private int turnInZone;
|
private int turnInZone;
|
||||||
@@ -2275,22 +2275,20 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// shield = regeneration
|
// shield = regeneration
|
||||||
public final Iterable<CardShields> getShields() {
|
public final Iterable<Card> getShields() {
|
||||||
return shields;
|
return shields;
|
||||||
}
|
}
|
||||||
public final int getShieldCount() {
|
public final int getShieldCount() {
|
||||||
return shields.size();
|
return shields.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void addShield(final CardShields shield) {
|
public final void addShield(final Card shield) {
|
||||||
shields.add(shield);
|
if (shields.add(shield)) {
|
||||||
view.updateShieldCount(this);
|
view.updateShieldCount(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void subtractShield(CardShields shield) {
|
public final void subtractShield(final Card shield) {
|
||||||
if (shield != null && shield.hasTrigger()) {
|
|
||||||
getGame().getStack().addSimultaneousStackEntry(shield.getTriggerSA());
|
|
||||||
}
|
|
||||||
if (shields.remove(shield)) {
|
if (shields.remove(shield)) {
|
||||||
view.updateShieldCount(this);
|
view.updateShieldCount(this);
|
||||||
}
|
}
|
||||||
@@ -5241,6 +5239,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
resetDealtDamageToPlayerThisTurn();
|
resetDealtDamageToPlayerThisTurn();
|
||||||
getDamageHistory().newTurn();
|
getDamageHistory().newTurn();
|
||||||
setRegeneratedThisTurn(0);
|
setRegeneratedThisTurn(0);
|
||||||
|
resetShield();
|
||||||
setBecameTargetThisTurn(false);
|
setBecameTargetThisTurn(false);
|
||||||
clearMustAttackEntity(turn);
|
clearMustAttackEntity(turn);
|
||||||
clearMustBlockCards();
|
clearMustBlockCards();
|
||||||
|
|||||||
@@ -3346,6 +3346,15 @@ public class CardFactoryUtil {
|
|||||||
|
|
||||||
final ReplacementEffect re = makeEtbCounter(sb.toString(), card, intrinsic);
|
final ReplacementEffect re = makeEtbCounter(sb.toString(), card, intrinsic);
|
||||||
|
|
||||||
|
inst.addReplacement(re);
|
||||||
|
} else if (keyword.equals("If CARDNAME would be destroyed, regenerate it.")) {
|
||||||
|
String repeffstr = "Event$ Destroy | ActiveZones$ Battlefield | ValidCard$ Card.Self"
|
||||||
|
+ " | Secondary$ True | Regeneration$ True | Description$ " + keyword;
|
||||||
|
String effect = "DB$ Regeneration | Defined$ ReplacedCard";
|
||||||
|
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, card, intrinsic);
|
||||||
|
SpellAbility sa = AbilityFactory.getAbility(effect, card);
|
||||||
|
re.setOverridingAbility(sa);
|
||||||
|
|
||||||
inst.addReplacement(re);
|
inst.addReplacement(re);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.getHostCard().getName() + suffix;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -196,7 +196,6 @@ public abstract class PlayerController {
|
|||||||
public abstract boolean confirmPayment(CostPart costPart, String string, SpellAbility sa);
|
public abstract boolean confirmPayment(CostPart costPart, String string, SpellAbility sa);
|
||||||
public abstract ReplacementEffect chooseSingleReplacementEffect(String prompt, List<ReplacementEffect> possibleReplacers, Map<String, Object> runParams);
|
public abstract ReplacementEffect chooseSingleReplacementEffect(String prompt, List<ReplacementEffect> possibleReplacers, Map<String, Object> runParams);
|
||||||
public abstract String chooseProtectionType(String string, SpellAbility sa, List<String> choices);
|
public abstract String chooseProtectionType(String string, SpellAbility sa, List<String> choices);
|
||||||
public abstract CardShields chooseRegenerationShield(Card c);
|
|
||||||
|
|
||||||
// these 4 need some refining.
|
// these 4 need some refining.
|
||||||
public abstract boolean payCostToPreventEffect(Cost cost, SpellAbility sa, boolean alreadyPaid, FCollectionView<Player> allPayers);
|
public abstract boolean payCostToPreventEffect(Cost cost, SpellAbility sa, boolean alreadyPaid, FCollectionView<Player> allPayers);
|
||||||
|
|||||||
@@ -46,18 +46,35 @@ public class ReplaceDestroy extends ReplacementEffect {
|
|||||||
if (!runParams.get("Event").equals("Destroy")) {
|
if (!runParams.get("Event").equals("Destroy")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (this.getMapParams().containsKey("ValidPlayer")) {
|
if (hasParam("ValidPlayer")) {
|
||||||
if (!matchesValid(runParams.get("Affected"), this.getMapParams().get("ValidPlayer").split(","), this.getHostCard())) {
|
if (!matchesValid(runParams.get("Affected"), getParam("ValidPlayer").split(","), getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.getMapParams().containsKey("ValidCard")) {
|
if (hasParam("ValidCard")) {
|
||||||
if (!matchesValid(runParams.get("Card"), this.getMapParams().get("ValidCard").split(","), this.getHostCard())) {
|
Card card = (Card)runParams.get("Card");
|
||||||
|
if (!matchesValid(card, getParam("ValidCard").split(","), getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// extra check for Regeneration
|
||||||
|
if (hasParam("Regeneration")) {
|
||||||
|
if (!runParams.containsKey("Regeneration")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(Boolean)runParams.get("Regeneration")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!card.canBeShielded()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (card.isCreature()) {
|
||||||
|
if (card.getNetToughness() <= 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (this.getMapParams().containsKey("ValidSource")) {
|
if (hasParam("ValidSource")) {
|
||||||
if (!matchesValid(runParams.get("Source"), this.getMapParams().get("ValidSource").split(","), this.getHostCard())) {
|
if (!matchesValid(runParams.get("Source"), getParam("ValidSource").split(","), getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
*/
|
*/
|
||||||
package forge.game.trigger;
|
package forge.game.trigger;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
|
|
||||||
@@ -42,22 +44,20 @@ public class TriggerDestroyed extends Trigger {
|
|||||||
* @param intrinsic
|
* @param intrinsic
|
||||||
* the intrinsic
|
* the intrinsic
|
||||||
*/
|
*/
|
||||||
public TriggerDestroyed(final java.util.Map<String, String> params, final Card host, final boolean intrinsic) {
|
public TriggerDestroyed(final Map<String, String> params, final Card host, final boolean intrinsic) {
|
||||||
super(params, host, intrinsic);
|
super(params, host, intrinsic);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public final boolean performTest(final java.util.Map<String, Object> runParams2) {
|
public final boolean performTest(final Map<String, Object> runParams2) {
|
||||||
if (this.mapParams.containsKey("ValidCauser")) {
|
if (hasParam("ValidCauser")) {
|
||||||
if (!matchesValid(runParams2.get("Causer"), this.mapParams.get("ValidCauser").split(","),
|
if (!matchesValid(runParams2.get("Causer"), getParam("ValidCauser").split(","), getHostCard())) {
|
||||||
this.getHostCard())) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.mapParams.containsKey("ValidCard")) {
|
if (hasParam("ValidCard")) {
|
||||||
if (!matchesValid(runParams2.get("Card"), this.mapParams.get("ValidCard").split(","),
|
if (!matchesValid(runParams2.get("Card"), getParam("ValidCard").split(","), getHostCard())) {
|
||||||
this.getHostCard())) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* 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.trigger;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import forge.game.card.Card;
|
||||||
|
import forge.game.spellability.SpellAbility;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Trigger_Destroyed class.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Forge
|
||||||
|
* @version $Id: TriggerDestroyed.java 17802 2012-10-31 08:05:14Z Max mtg $
|
||||||
|
*/
|
||||||
|
public class TriggerRegenerated extends Trigger {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Constructor for Trigger_Destroyed.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param params
|
||||||
|
* a {@link java.util.HashMap} object.
|
||||||
|
* @param host
|
||||||
|
* a {@link forge.game.card.Card} object.
|
||||||
|
* @param intrinsic
|
||||||
|
* the intrinsic
|
||||||
|
*/
|
||||||
|
public TriggerRegenerated(final Map<String, String> params, final Card host, final boolean intrinsic) {
|
||||||
|
super(params, host, intrinsic);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public final boolean performTest(final Map<String, Object> runParams2) {
|
||||||
|
if (hasParam("ValidCause")) {
|
||||||
|
if (!matchesValid(runParams2.get("Cause"), getParam("ValidCause").split(","), getHostCard())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasParam("ValidCard")) {
|
||||||
|
if (!matchesValid(runParams2.get("Card"), getParam("ValidCard").split(","), getHostCard())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public final void setTriggeringObjects(final SpellAbility sa) {
|
||||||
|
sa.setTriggeringObject("Card", this.getRunParams().get("Card"));
|
||||||
|
sa.setTriggeringObject("Cause", this.getRunParams().get("Cause"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getImportantStackObjects(SpellAbility sa) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("Regenerated: ").append(sa.getTriggeringObject("Card"));
|
||||||
|
//sb.append("Destroyer: ").append(sa.getTriggeringObject("Causer"));
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -67,6 +67,7 @@ public enum TriggerType {
|
|||||||
PlanarDice(TriggerPlanarDice.class),
|
PlanarDice(TriggerPlanarDice.class),
|
||||||
PlaneswalkedFrom(TriggerPlaneswalkedFrom.class),
|
PlaneswalkedFrom(TriggerPlaneswalkedFrom.class),
|
||||||
PlaneswalkedTo(TriggerPlaneswalkedTo.class),
|
PlaneswalkedTo(TriggerPlaneswalkedTo.class),
|
||||||
|
Regenerated(TriggerRegenerated.class),
|
||||||
Revealed(TriggerRevealed.class),
|
Revealed(TriggerRevealed.class),
|
||||||
Sacrificed(TriggerSacrificed.class),
|
Sacrificed(TriggerSacrificed.class),
|
||||||
Scry(TriggerScry.class),
|
Scry(TriggerScry.class),
|
||||||
|
|||||||
@@ -566,11 +566,6 @@ public class PlayerControllerForTests extends PlayerController {
|
|||||||
// test this!
|
// test this!
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public CardShields chooseRegenerationShield(Card c) {
|
|
||||||
return Iterables.getFirst(c.getShields(), null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<PaperCard> chooseCardsYouWonToAddToDeck(List<PaperCard> losses) {
|
public List<PaperCard> chooseCardsYouWonToAddToDeck(List<PaperCard> losses) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
Name:Debt of Loyalty
|
Name:Debt of Loyalty
|
||||||
ManaCost:1 W W
|
ManaCost:1 W W
|
||||||
Types:Instant
|
Types:Instant
|
||||||
A:SP$ Regenerate | Cost$ 1 W W | ValidTgts$ Creature | TgtPrompt$ Select target creature | RegenerationTrigger$ TrigGainControl | ReplaceCardUID$ Targeted | SpellDescription$ Regenerate target creature. You gain control of that creature if it regenerates this way.
|
A:SP$ Regenerate | Cost$ 1 W W | ValidTgts$ Creature | TgtPrompt$ Select target creature | RegenerationTrigger$ TrigGainControl | References$ TrigGainControl | SpellDescription$ Regenerate target creature. You gain control of that creature if it regenerates this way.
|
||||||
SVar:TrigGainControl:ST$ GainControl | Cost$ 0 | Defined$ CardUID_Targeted | NewController$ You | SpellDescription$ Source controller gains control of CARDNAME if it regenerates this way.
|
SVar:TrigGainControl:ST$ GainControl | Cost$ 0 | Defined$ TriggeredCard | NewController$ You | SpellDescription$ Source controller gains control of CARDNAME if it regenerates this way.
|
||||||
SVar:RemAIDeck:True
|
SVar:RemAIDeck:True
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/debt_of_loyalty.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/debt_of_loyalty.jpg
|
||||||
Oracle:Regenerate target creature. You gain control of that creature if it regenerates this way.
|
Oracle:Regenerate target creature. You gain control of that creature if it regenerates this way.
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ Name:Matopi Golem
|
|||||||
ManaCost:5
|
ManaCost:5
|
||||||
Types:Artifact Creature Golem
|
Types:Artifact Creature Golem
|
||||||
PT:3/3
|
PT:3/3
|
||||||
A:AB$ Regenerate | Cost$ 1 | RegenerationTrigger$ TrigPutCounter | SpellDescription$ Regenerate CARDNAME. When it regenerates this way, put a -1/-1 counter on it.
|
A:AB$ Regenerate | Cost$ 1 | RegenerationTrigger$ TrigPutCounter | References$ TrigPutCounter | SpellDescription$ Regenerate CARDNAME. When it regenerates this way, put a -1/-1 counter on it.
|
||||||
SVar:TrigPutCounter:DB$ PutCounter | CounterType$ M1M1 | CounterNum$ 1 | SpellDescription$ When it regenerates this way, put a -1/-1 counter on it.
|
SVar:TrigPutCounter:DB$ PutCounter | Defined$ TriggeredCard | CounterType$ M1M1 | CounterNum$ 1 | SpellDescription$ When it regenerates this way, put a -1/-1 counter on it.
|
||||||
|
DeckHas:Ability$Counters
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/matopi_golem.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/matopi_golem.jpg
|
||||||
Oracle:{1}: Regenerate Matopi Golem. When it regenerates this way, put a -1/-1 counter on it.
|
Oracle:{1}: Regenerate Matopi Golem. When it regenerates this way, put a -1/-1 counter on it.
|
||||||
|
|||||||
@@ -3,8 +3,9 @@ ManaCost:2 B
|
|||||||
Types:Creature Skeleton
|
Types:Creature Skeleton
|
||||||
PT:0/0
|
PT:0/0
|
||||||
K:etbCounter:P1P1:1
|
K:etbCounter:P1P1:1
|
||||||
A:AB$ Regenerate | Cost$ X | CostDesc$ Pay {1} for each +1/+1 counter on CARDNAME: | References$ X | RegenerationTrigger$ TrigPutCounter | SpellDescription$ Regenerate CARDNAME. When it regenerates this way, put a +1/+1 counter on it.
|
A:AB$ Regenerate | Cost$ X | CostDesc$ Pay {1} for each +1/+1 counter on CARDNAME: | References$ X,TrigPutCounter | RegenerationTrigger$ TrigPutCounter | SpellDescription$ Regenerate CARDNAME. When it regenerates this way, put a +1/+1 counter on it.
|
||||||
|
SVar:TrigPutCounter:DB$ PutCounter | Defined$ TriggeredCard | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ When it regenerates this way, put a +1/+1 counter on it.
|
||||||
SVar:X:Count$CardCounters.P1P1
|
SVar:X:Count$CardCounters.P1P1
|
||||||
SVar:TrigPutCounter:DB$ PutCounter | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ When it regenerates this way, put a +1/+1 counter on it.
|
DeckHas:Ability$Counters
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/skeleton_scavengers.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/skeleton_scavengers.jpg
|
||||||
Oracle:Skeleton Scavengers enters the battlefield with a +1/+1 counter on it.\nPay {1} for each +1/+1 counter on Skeleton Scavengers: Regenerate Skeleton Scavengers. When it regenerates this way, put a +1/+1 counter on it.
|
Oracle:Skeleton Scavengers enters the battlefield with a +1/+1 counter on it.\nPay {1} for each +1/+1 counter on Skeleton Scavengers: Regenerate Skeleton Scavengers. When it regenerates this way, put a +1/+1 counter on it.
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ Name:Soldevi Sentry
|
|||||||
ManaCost:1
|
ManaCost:1
|
||||||
Types:Artifact Creature Soldier
|
Types:Artifact Creature Soldier
|
||||||
PT:1/1
|
PT:1/1
|
||||||
A:AB$ Regenerate | Cost$ 1 | ValidTgts$ Opponent | Defined$ Self | RegenerationTrigger$ TrigDraw | ReplacePlayerName$ Targeted | SpellDescription$ Choose target opponent. Regenerate CARDNAME. When it regenerates this way, that player may draw a card.
|
A:AB$ Regenerate | Cost$ 1 | ValidTgts$ Opponent | Defined$ Self | RegenerationTrigger$ TrigDraw | RememberObjects$ TargetedPlayer | References$ TrigDraw | SpellDescription$ Choose target opponent. Regenerate CARDNAME. When it regenerates this way, that player may draw a card.
|
||||||
SVar:TrigDraw:DB$ Draw | Defined$ PlayerNamed_Targeted | NumCards$ 1 | OptionalDecider$ True | SpellDescription$ When it regenerates this way, that player may draw a card.
|
SVar:TrigDraw:DB$ Draw | Defined$ Remembered | NumCards$ 1 | OptionalDecider$ True | SpellDescription$ When it regenerates this way, that player may draw a card.
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/soldevi_sentry.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/soldevi_sentry.jpg
|
||||||
Oracle:{1}: Choose target opponent. Regenerate Soldevi Sentry. When it regenerates this way, that player may draw a card.
|
Oracle:{1}: Choose target opponent. Regenerate Soldevi Sentry. When it regenerates this way, that player may draw a card.
|
||||||
|
|||||||
@@ -1569,18 +1569,6 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public CardShields chooseRegenerationShield(final Card c) {
|
|
||||||
if (c.getShieldCount() < 2) {
|
|
||||||
return Iterables.getFirst(c.getShields(), null);
|
|
||||||
}
|
|
||||||
final List<CardShields> shields = Lists.newArrayList();
|
|
||||||
for (final CardShields shield : c.getShields()) {
|
|
||||||
shields.add(shield);
|
|
||||||
}
|
|
||||||
return getGui().one("Choose a regeneration shield:", shields);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<PaperCard> chooseCardsYouWonToAddToDeck(final List<PaperCard> losses) {
|
public List<PaperCard> chooseCardsYouWonToAddToDeck(final List<PaperCard> losses) {
|
||||||
return getGui().many("Select cards to add to your deck", "Add these to my deck", 0, losses.size(), losses,
|
return getGui().many("Select cards to add to your deck", "Add these to my deck", 0, losses.size(), losses,
|
||||||
|
|||||||
Reference in New Issue
Block a user