mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 11:48:02 +00:00
SpellAbility: now does store the SubAbilities which are used by some Effects,
that makes it working to copy them to other cards. rewrite Entwine to use CardFactoryUtil
This commit is contained in:
@@ -264,17 +264,6 @@ public final class GameActionUtil {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
} else if (keyword.startsWith("Entwine")) {
|
||||
for (int i = 0; i < abilities.size(); i++) {
|
||||
final SpellAbility newSA = abilities.get(i).copy();
|
||||
SpellAbility entwine = AbilityFactory.buildEntwineAbility(newSA);
|
||||
entwine.setPayCosts(new Cost(keyword.substring(8), false).add(newSA.getPayCosts()));
|
||||
entwine.addOptionalCost(OptionalCost.Entwine);
|
||||
if (newSA.canPlay()) {
|
||||
abilities.add(i, entwine);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
} else if (keyword.startsWith("Kicker")) {
|
||||
String[] sCosts = TextUtil.split(keyword.substring(6), ':');
|
||||
boolean generic = "Generic".equals(sCosts[sCosts.length - 1]);
|
||||
|
||||
@@ -28,6 +28,7 @@ import forge.util.FileSection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
/**
|
||||
@@ -40,6 +41,15 @@ import com.google.common.collect.Lists;
|
||||
*/
|
||||
public final class AbilityFactory {
|
||||
|
||||
static final List<String> additionalAbilityKeys = Lists.newArrayList(
|
||||
"WinSubAbility", "OtherwiseSubAbility", // Clash
|
||||
"ChooseNumberSubAbility", "Lowest", "Highest", // ChooseNumber
|
||||
"HeadsSubAbility", "TailsSubAbility", "LoseSubAbility", // FlipCoin
|
||||
"ChosenPile", "UnchosenPile", // MultiplePiles & TwoPiles
|
||||
"RepeatSubAbility", // Repeat & RepeatEach
|
||||
"Execute" // DelayedTrigger
|
||||
);
|
||||
|
||||
public enum AbilityRecordType {
|
||||
Ability("AB"),
|
||||
Spell("SP"),
|
||||
@@ -136,7 +146,7 @@ public final class AbilityFactory {
|
||||
return abCost;
|
||||
}
|
||||
|
||||
public static final SpellAbility getAbility(AbilityRecordType type, ApiType api, Map<String, String> mapParams, Cost abCost, Card hostCard) {
|
||||
public static final SpellAbility getAbility(AbilityRecordType type, ApiType api, Map<String, String> mapParams, Cost abCost,final Card hostCard) {
|
||||
TargetRestrictions abTgt = mapParams.containsKey("ValidTgts") ? readTarget(mapParams) : null;
|
||||
|
||||
if (api == ApiType.CopySpellAbility || api == ApiType.Counter || api == ApiType.ChangeTargets || api == ApiType.ControlSpell) {
|
||||
@@ -181,10 +191,6 @@ public final class AbilityFactory {
|
||||
spellAbility.setSVar(mapParams.get("Execute"), hostCard.getSVar(mapParams.get("Execute")));
|
||||
}
|
||||
|
||||
if (api == ApiType.RepeatEach) {
|
||||
spellAbility.setSVar(mapParams.get("RepeatSubAbility"), hostCard.getSVar(mapParams.get("RepeatSubAbility")));
|
||||
}
|
||||
|
||||
if (mapParams.containsKey("PreventionSubAbility")) {
|
||||
spellAbility.setSVar(mapParams.get("PreventionSubAbility"), hostCard.getSVar(mapParams.get("PreventionSubAbility")));
|
||||
}
|
||||
@@ -193,6 +199,25 @@ public final class AbilityFactory {
|
||||
spellAbility.setSubAbility(getSubAbility(hostCard, mapParams.get("SubAbility")));
|
||||
}
|
||||
|
||||
for (final String key : additionalAbilityKeys) {
|
||||
if (mapParams.containsKey(key)) {
|
||||
spellAbility.setAdditionalAbility(key, getSubAbility(hostCard, mapParams.get(key)));
|
||||
}
|
||||
}
|
||||
|
||||
if (api == ApiType.Charm || api == ApiType.GenericChoice) {
|
||||
final String key = "Choices";
|
||||
if (mapParams.containsKey(key)) {
|
||||
List<String> names = Lists.newArrayList(mapParams.get(key).split(","));
|
||||
spellAbility.setAdditionalAbilityList(key, Lists.transform(names, new Function<String, AbilitySub>() {
|
||||
@Override
|
||||
public AbilitySub apply(String input) {
|
||||
return getSubAbility(hostCard, input);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
if (spellAbility instanceof SpellApiBased && hostCard.isPermanent()) {
|
||||
spellAbility.setDescription(spellAbility.getHostCard().getName());
|
||||
} else if (mapParams.containsKey("SpellDescription")) {
|
||||
@@ -211,7 +236,7 @@ public final class AbilityFactory {
|
||||
} else {
|
||||
spellAbility.setDescription("");
|
||||
}
|
||||
|
||||
|
||||
initializeParams(spellAbility, mapParams);
|
||||
makeRestrictions(spellAbility, mapParams);
|
||||
makeConditions(spellAbility, mapParams);
|
||||
@@ -395,32 +420,4 @@ public final class AbilityFactory {
|
||||
left.appendSubAbility(right);
|
||||
return left;
|
||||
}
|
||||
|
||||
public static final SpellAbility buildEntwineAbility(final SpellAbility sa) {
|
||||
final Card source = sa.getHostCard();
|
||||
final String[] saChoices = sa.getParam("Choices").split(",");
|
||||
if (sa.getApi() != ApiType.Charm || saChoices.length != 2)
|
||||
throw new IllegalStateException("Entwine ability may be built only on charm cards");
|
||||
final String ab = source.getSVar(saChoices[0]);
|
||||
Map<String, String> firstMap = getMapParams(ab);
|
||||
AbilityRecordType firstType = AbilityRecordType.getRecordType(firstMap);
|
||||
ApiType firstApi = firstType.getApiTypeOf(firstMap);
|
||||
firstMap.put("StackDecription", firstMap.get("SpellDescription"));
|
||||
firstMap.put("SpellDescription", sa.getDescription() + " Entwine (Choose both if you pay the entwine cost.)");
|
||||
SpellAbility entwineSA = getAbility(AbilityRecordType.Spell, firstApi, firstMap, new Cost(sa.getPayCosts().toSimpleString(), false), source);
|
||||
|
||||
final String ab2 = source.getSVar(saChoices[1]);
|
||||
Map<String, String> secondMap = getMapParams(ab2);
|
||||
ApiType secondApi = firstType.getApiTypeOf(secondMap);
|
||||
secondMap.put("StackDecription", secondMap.get("SpellDescription"));
|
||||
secondMap.put("SpellDescription", "");
|
||||
AbilitySub sub = (AbilitySub) getAbility(AbilityRecordType.SubAbility, secondApi, secondMap, null, source);
|
||||
entwineSA.appendSubAbility(sub);
|
||||
|
||||
entwineSA.setBasicSpell(false);
|
||||
entwineSA.setActivatingPlayer(sa.getActivatingPlayer());
|
||||
entwineSA.setRestrictions(sa.getRestrictions());
|
||||
return entwineSA;
|
||||
}
|
||||
|
||||
} // end class AbilityFactory
|
||||
|
||||
@@ -5,7 +5,6 @@ import forge.game.Game;
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.GameObject;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.ApiType;
|
||||
import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardCollection;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package forge.game.ability.effects;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import forge.game.ability.AbilityFactory;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.player.Player;
|
||||
@@ -10,7 +10,6 @@ import forge.game.spellability.SpellAbility;
|
||||
import forge.util.Lang;
|
||||
import forge.util.collect.FCollection;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
@@ -20,7 +19,6 @@ public class CharmEffect extends SpellAbilityEffect {
|
||||
public static List<AbilitySub> makePossibleOptions(final SpellAbility sa) {
|
||||
final Card source = sa.getHostCard();
|
||||
Iterable<Object> restriction = null;
|
||||
final String[] saChoices = sa.getParam("Choices").split(",");
|
||||
|
||||
if (sa.hasParam("ChoiceRestriction")) {
|
||||
String rest = sa.getParam("ChoiceRestriction");
|
||||
@@ -28,24 +26,16 @@ public class CharmEffect extends SpellAbilityEffect {
|
||||
restriction = source.getRemembered();
|
||||
}
|
||||
}
|
||||
|
||||
List<AbilitySub> choices = new ArrayList<AbilitySub>();
|
||||
|
||||
int indx = 0;
|
||||
for (final String saChoice : saChoices) {
|
||||
if (restriction != null && Iterables.contains(restriction, saChoice)) {
|
||||
// If there is a choice restriction, and the current choice fails that, skip it.
|
||||
continue;
|
||||
}
|
||||
final String ab = source.getSVar(saChoice);
|
||||
AbilitySub sub = (AbilitySub) AbilityFactory.getAbility(ab, source);
|
||||
if (sa.isIntrinsic()) {
|
||||
sub.setIntrinsic(true);
|
||||
sub.changeText();
|
||||
}
|
||||
List<AbilitySub> choices = sa.getAdditionalAbilityList("Choices");
|
||||
if (restriction != null) {
|
||||
choices.removeAll(Lists.newArrayList(restriction));
|
||||
}
|
||||
// set CharmOrder
|
||||
for (AbilitySub sub : choices) {
|
||||
sub.setTrigger(sa.isTrigger());
|
||||
|
||||
sub.setSVar("CharmOrder", Integer.toString(indx));
|
||||
choices.add(sub);
|
||||
indx++;
|
||||
}
|
||||
return choices;
|
||||
@@ -138,6 +128,12 @@ public class CharmEffect extends SpellAbilityEffect {
|
||||
//this resets all previous choices
|
||||
sa.setSubAbility(null);
|
||||
|
||||
// Entwine does use all Choices
|
||||
if (sa.isEntwine()) {
|
||||
chainAbilities(sa, makePossibleOptions(sa));
|
||||
return;
|
||||
}
|
||||
|
||||
final int num = Integer.parseInt(sa.hasParam("CharmNum") ? sa.getParam("CharmNum") : "1");
|
||||
final int min = sa.hasParam("MinCharmNum") ? Integer.parseInt(sa.getParam("MinCharmNum")) : num;
|
||||
|
||||
@@ -165,7 +161,7 @@ public class CharmEffect extends SpellAbilityEffect {
|
||||
Collections.sort(chosen, new Comparator<AbilitySub>() {
|
||||
@Override
|
||||
public int compare(AbilitySub o1, AbilitySub o2) {
|
||||
return Integer.parseInt(o1.getSVar("CharmOrder")) - Integer.parseInt(o2.getSVar("CharmOrder"));
|
||||
return Integer.compare(o1.getSVarInt("CharmOrder"), o2.getSVarInt("CharmOrder"));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
package forge.game.ability.effects;
|
||||
|
||||
import forge.game.ability.AbilityFactory;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.event.GameEventCardModeChosen;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.AbilitySub;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.TargetRestrictions;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
public class ChooseGenericEffect extends SpellAbilityEffect {
|
||||
|
||||
@Override
|
||||
@@ -31,12 +30,8 @@ public class ChooseGenericEffect extends SpellAbilityEffect {
|
||||
@Override
|
||||
public void resolve(SpellAbility sa) {
|
||||
final Card host = sa.getHostCard();
|
||||
final String[] choices = sa.getParam("Choices").split(",");
|
||||
final List<SpellAbility> abilities = new ArrayList<SpellAbility>();
|
||||
|
||||
for (String s : choices) {
|
||||
abilities.add(AbilityFactory.getAbility(host.getSVar(s), host));
|
||||
}
|
||||
|
||||
final List<SpellAbility> abilities = Lists.<SpellAbility>newArrayList(sa.getAdditionalAbilityList("Choices"));
|
||||
|
||||
final List<Player> tgtPlayers = getDefinedPlayersOrTargeted(sa);
|
||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||
@@ -46,24 +41,18 @@ public class ChooseGenericEffect extends SpellAbilityEffect {
|
||||
continue;
|
||||
}
|
||||
|
||||
int idxChosen = 0;
|
||||
String chosenName;
|
||||
SpellAbility chosenSA = null;
|
||||
if (sa.hasParam("AtRandom")) {
|
||||
idxChosen = MyRandom.getRandom().nextInt(choices.length);
|
||||
chosenName = choices[idxChosen];
|
||||
int idxChosen = MyRandom.getRandom().nextInt(abilities.size());
|
||||
chosenSA = abilities.get(idxChosen);
|
||||
} else {
|
||||
SpellAbility saChosen = p.getController().chooseSingleSpellForEffect(abilities, sa, "Choose one");
|
||||
idxChosen = abilities.indexOf(saChosen);
|
||||
chosenName = choices[idxChosen];
|
||||
chosenSA = p.getController().chooseSingleSpellForEffect(abilities, sa, "Choose one");
|
||||
}
|
||||
SpellAbility chosenSA = AbilityFactory.getAbility(host.getSVar(chosenName), host);
|
||||
String chosenValue = abilities.get(idxChosen).getDescription();
|
||||
String chosenValue = chosenSA.getDescription();
|
||||
if (sa.hasParam("ShowChoice")) {
|
||||
boolean dontNotifySelf = sa.getParam("ShowChoice").equals("ExceptSelf");
|
||||
p.getGame().getAction().nofityOfValue(sa, p, chosenValue, dontNotifySelf ? sa.getActivatingPlayer() : null);
|
||||
}
|
||||
chosenSA.setActivatingPlayer(sa.getActivatingPlayer());
|
||||
((AbilitySub) chosenSA).setParent(sa);
|
||||
p.getGame().fireEvent(new GameEventCardModeChosen(p, host.getName(), chosenValue, sa.hasParam("ShowChoice")));
|
||||
AbilityUtils.resolve(chosenSA);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package forge.game.ability.effects;
|
||||
|
||||
import forge.game.ability.AbilityFactory;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.Card;
|
||||
@@ -9,11 +8,13 @@ import forge.game.spellability.AbilitySub;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.TargetRestrictions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class ChooseNumberEffect extends SpellAbilityEffect {
|
||||
@@ -49,7 +50,7 @@ public class ChooseNumberEffect extends SpellAbilityEffect {
|
||||
|
||||
final List<Player> tgtPlayers = getTargetPlayers(sa);
|
||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||
final Map<Player, Integer> chooseMap = new HashMap<Player, Integer>();
|
||||
final Map<Player, Integer> chooseMap = Maps.newHashMap();
|
||||
|
||||
for (final Player p : tgtPlayers) {
|
||||
if ((tgt == null) || p.canBeTargetedBy(sa)) {
|
||||
@@ -80,8 +81,8 @@ public class ChooseNumberEffect extends SpellAbilityEffect {
|
||||
}
|
||||
if (secretlyChoose) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
List<Player> highestNum = new ArrayList<Player>();
|
||||
List<Player> lowestNum = new ArrayList<Player>();
|
||||
List<Player> highestNum = Lists.newArrayList();
|
||||
List<Player> lowestNum = Lists.newArrayList();
|
||||
int highest = 0;
|
||||
int lowest = Integer.MAX_VALUE;
|
||||
for (Entry<Player, Integer> ev : chooseMap.entrySet()) {
|
||||
@@ -106,13 +107,8 @@ public class ChooseNumberEffect extends SpellAbilityEffect {
|
||||
}
|
||||
card.getGame().getAction().nofityOfValue(sa, card, sb.toString(), null);
|
||||
if (sa.hasParam("ChooseNumberSubAbility")) {
|
||||
SpellAbility sub = AbilityFactory.getAbility(card.getSVar(sa.getParam("ChooseNumberSubAbility")), card);
|
||||
if (sa.isIntrinsic()) {
|
||||
sub.setIntrinsic(true);
|
||||
sub.changeText();
|
||||
}
|
||||
sub.setActivatingPlayer(sa.getActivatingPlayer());
|
||||
((AbilitySub) sub).setParent(sa);
|
||||
AbilitySub sub = sa.getAdditonalAbility("ChooseNumberSubAbility");
|
||||
|
||||
for (Player p : chooseMap.keySet()) {
|
||||
card.addRemembered(p);
|
||||
card.setChosenNumber(chooseMap.get(p));
|
||||
@@ -122,32 +118,22 @@ public class ChooseNumberEffect extends SpellAbilityEffect {
|
||||
}
|
||||
|
||||
if (sa.hasParam("Lowest")) {
|
||||
SpellAbility action = AbilityFactory.getAbility(card.getSVar(sa.getParam("Lowest")), card);
|
||||
if (sa.isIntrinsic()) {
|
||||
action.setIntrinsic(true);
|
||||
action.changeText();
|
||||
}
|
||||
action.setActivatingPlayer(sa.getActivatingPlayer());
|
||||
((AbilitySub) action).setParent(sa);
|
||||
AbilitySub sub = sa.getAdditonalAbility("Lowest");
|
||||
|
||||
for (Player p : lowestNum) {
|
||||
card.addRemembered(p);
|
||||
card.setChosenNumber(lowest);
|
||||
AbilityUtils.resolve(action);
|
||||
AbilityUtils.resolve(sub);
|
||||
card.clearRemembered();
|
||||
}
|
||||
}
|
||||
if (sa.hasParam("Highest")) {
|
||||
SpellAbility action = AbilityFactory.getAbility(card.getSVar(sa.getParam("Highest")), card);
|
||||
if (sa.isIntrinsic()) {
|
||||
action.setIntrinsic(true);
|
||||
action.changeText();
|
||||
}
|
||||
action.setActivatingPlayer(sa.getActivatingPlayer());
|
||||
((AbilitySub) action).setParent(sa);
|
||||
AbilitySub sub = sa.getAdditonalAbility("Highest");
|
||||
|
||||
for (Player p : highestNum) {
|
||||
card.addRemembered(p);
|
||||
card.setChosenNumber(highest);
|
||||
AbilityUtils.resolve(action);
|
||||
AbilityUtils.resolve(sub);
|
||||
card.clearRemembered();
|
||||
}
|
||||
if (sa.hasParam("RememberHighest")) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package forge.game.ability.effects;
|
||||
|
||||
import forge.game.GameAction;
|
||||
import forge.game.ability.AbilityFactory;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.Card;
|
||||
@@ -36,32 +35,19 @@ public class ClashEffect extends SpellAbilityEffect {
|
||||
runParams.put("Player", sa.getHostCard().getController());
|
||||
|
||||
if (victory) {
|
||||
if (sa.hasParam("WinSubAbility")) {
|
||||
final SpellAbility win = AbilityFactory.getAbility(
|
||||
sa.getHostCard().getSVar(sa.getParam("WinSubAbility")), sa.getHostCard());
|
||||
if (sa.isIntrinsic()) {
|
||||
win.setIntrinsic(true);
|
||||
win.changeText();
|
||||
}
|
||||
win.setActivatingPlayer(sa.getHostCard().getController());
|
||||
((AbilitySub) win).setParent(sa);
|
||||
|
||||
AbilityUtils.resolve(win);
|
||||
AbilitySub sub = sa.getAdditonalAbility("WinSubAbility");
|
||||
if (sub != null) {
|
||||
AbilityUtils.resolve(sub);
|
||||
}
|
||||
|
||||
runParams.put("Won", "True");
|
||||
} else {
|
||||
if (sa.hasParam("OtherwiseSubAbility")) {
|
||||
final SpellAbility otherwise = AbilityFactory.getAbility(
|
||||
sa.getHostCard().getSVar(sa.getParam("OtherwiseSubAbility")), sa.getHostCard());
|
||||
if (sa.isIntrinsic()) {
|
||||
otherwise.setIntrinsic(true);
|
||||
otherwise.changeText();
|
||||
}
|
||||
otherwise.setActivatingPlayer(sa.getHostCard().getController());
|
||||
((AbilitySub) otherwise).setParent(sa);
|
||||
|
||||
AbilityUtils.resolve(otherwise);
|
||||
AbilitySub sub = sa.getAdditonalAbility("OtherwiseSubAbility");
|
||||
if (sub != null) {
|
||||
AbilityUtils.resolve(sub);
|
||||
}
|
||||
|
||||
runParams.put("Won", "False");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package forge.game.ability.effects;
|
||||
|
||||
import forge.game.ability.AbilityFactory;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.ApiType;
|
||||
import forge.game.ability.SpellAbilityEffect;
|
||||
@@ -13,6 +12,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
public class DelayedTriggerEffect extends SpellAbilityEffect {
|
||||
|
||||
@@ -31,9 +31,7 @@ public class DelayedTriggerEffect extends SpellAbilityEffect {
|
||||
|
||||
@Override
|
||||
public void resolve(SpellAbility sa) {
|
||||
|
||||
Map<String, String> mapParams = new HashMap<String, String>();
|
||||
sa.copyParamsToMap(mapParams);
|
||||
Map<String, String> mapParams = Maps.newHashMap(sa.getMapParams());
|
||||
if (mapParams.containsKey("Cost")) {
|
||||
mapParams.remove("Cost");
|
||||
}
|
||||
@@ -75,7 +73,7 @@ public class DelayedTriggerEffect extends SpellAbilityEffect {
|
||||
}
|
||||
|
||||
if (mapParams.containsKey("Execute")) {
|
||||
SpellAbility overridingSA = AbilityFactory.getAbility(sa.getSVar(mapParams.get("Execute")), sa.getHostCard());
|
||||
SpellAbility overridingSA = sa.getAdditonalAbility("Execute");
|
||||
overridingSA.setActivatingPlayer(sa.getActivatingPlayer());
|
||||
// Set Transform timestamp when the delayed trigger is created
|
||||
if (ApiType.SetState == overridingSA.getApi()) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package forge.game.ability.effects;
|
||||
|
||||
import forge.game.GameObject;
|
||||
import forge.game.ability.AbilityFactory;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.Card;
|
||||
@@ -13,8 +12,10 @@ import forge.game.spellability.SpellAbility;
|
||||
import forge.game.trigger.TriggerType;
|
||||
import forge.util.MyRandom;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
public class FlipCoinEffect extends SpellAbilityEffect {
|
||||
|
||||
@@ -73,28 +74,14 @@ public class FlipCoinEffect extends SpellAbilityEffect {
|
||||
}
|
||||
|
||||
if (resultIsHeads) {
|
||||
if (sa.hasParam("HeadsSubAbility")) {
|
||||
final SpellAbility heads = AbilityFactory.getAbility(host.getSVar(sa.getParam("HeadsSubAbility")), host);
|
||||
if (sa.isIntrinsic()) {
|
||||
heads.setIntrinsic(true);
|
||||
heads.changeText();
|
||||
}
|
||||
heads.setActivatingPlayer(player);
|
||||
((AbilitySub) heads).setParent(sa);
|
||||
|
||||
AbilityUtils.resolve(heads);
|
||||
AbilitySub sub = sa.getAdditonalAbility("HeadsSubAbility");
|
||||
if (sub != null) {
|
||||
AbilityUtils.resolve(sub);
|
||||
}
|
||||
} else {
|
||||
if (sa.hasParam("TailsSubAbility")) {
|
||||
final SpellAbility tails = AbilityFactory.getAbility(host.getSVar(sa.getParam("TailsSubAbility")), host);
|
||||
if (sa.isIntrinsic()) {
|
||||
tails.setIntrinsic(true);
|
||||
tails.changeText();
|
||||
}
|
||||
tails.setActivatingPlayer(player);
|
||||
((AbilitySub) tails).setParent(sa);
|
||||
|
||||
AbilityUtils.resolve(tails);
|
||||
AbilitySub sub = sa.getAdditonalAbility("TailsSubAbility");
|
||||
if (sub != null) {
|
||||
AbilityUtils.resolve(sub);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -102,32 +89,19 @@ public class FlipCoinEffect extends SpellAbilityEffect {
|
||||
if (sa.getParam("RememberWinner") != null) {
|
||||
host.addRemembered(host);
|
||||
}
|
||||
if (sa.hasParam("WinSubAbility")) {
|
||||
final SpellAbility win = AbilityFactory.getAbility(host.getSVar(sa.getParam("WinSubAbility")), host);
|
||||
if (sa.isIntrinsic()) {
|
||||
win.setIntrinsic(true);
|
||||
win.changeText();
|
||||
}
|
||||
win.setActivatingPlayer(player);
|
||||
((AbilitySub) win).setParent(sa);
|
||||
|
||||
AbilityUtils.resolve(win);
|
||||
AbilitySub sub = sa.getAdditonalAbility("WinSubAbility");
|
||||
if (sub != null) {
|
||||
AbilityUtils.resolve(sub);
|
||||
}
|
||||
// runParams.put("Won","True");
|
||||
} else {
|
||||
if (sa.getParam("RememberLoser") != null) {
|
||||
host.addRemembered(host);
|
||||
}
|
||||
if (sa.hasParam("LoseSubAbility")) {
|
||||
final SpellAbility lose = AbilityFactory.getAbility(host.getSVar(sa.getParam("LoseSubAbility")), host);
|
||||
if (sa.isIntrinsic()) {
|
||||
lose.setIntrinsic(true);
|
||||
lose.changeText();
|
||||
}
|
||||
lose.setActivatingPlayer(player);
|
||||
((AbilitySub) lose).setParent(sa);
|
||||
|
||||
AbilityUtils.resolve(lose);
|
||||
AbilitySub sub = sa.getAdditonalAbility("LoseSubAbility");
|
||||
if (sub != null) {
|
||||
AbilityUtils.resolve(sub);
|
||||
}
|
||||
// runParams.put("Won","False");
|
||||
}
|
||||
@@ -186,7 +160,7 @@ public class FlipCoinEffect extends SpellAbilityEffect {
|
||||
caller.getGame().getAction().nofityOfValue(sa, caller, result ? "win" : "lose", null);
|
||||
|
||||
// Run triggers
|
||||
HashMap<String,Object> runParams = new HashMap<String,Object>();
|
||||
Map<String,Object> runParams = Maps.newHashMap();
|
||||
runParams.put("Player", caller);
|
||||
runParams.put("Result", Boolean.valueOf(result));
|
||||
caller.getGame().getTriggerHandler().runTrigger(TriggerType.FlippedCoin, runParams, false);
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package forge.game.ability.effects;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import forge.game.ability.AbilityFactory;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.Card;
|
||||
@@ -16,8 +17,6 @@ import forge.game.spellability.TargetRestrictions;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.Aggregates;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@@ -57,7 +56,7 @@ public class MultiplePilesEffect extends SpellAbilityEffect {
|
||||
final ZoneType zone = sa.hasParam("Zone") ? ZoneType.smartValueOf(sa.getParam("Zone")) : ZoneType.Battlefield;
|
||||
final boolean randomChosen = sa.hasParam("RandomChosen");
|
||||
final int piles = Integer.parseInt(sa.getParam("Piles"));
|
||||
final Map<Player, List<CardCollectionView>> record = new HashMap<Player, List<CardCollectionView>>();
|
||||
final Map<Player, List<CardCollectionView>> record = Maps.newHashMap();
|
||||
|
||||
String valid = "";
|
||||
if (sa.hasParam("ValidCards")) {
|
||||
@@ -83,7 +82,7 @@ public class MultiplePilesEffect extends SpellAbilityEffect {
|
||||
}
|
||||
pool = CardLists.getValidCards(pool, valid, source.getController(), source);
|
||||
|
||||
List<CardCollectionView> pileList = new ArrayList<CardCollectionView>();
|
||||
List<CardCollectionView> pileList = Lists.newArrayList();
|
||||
|
||||
for (int i = 1; i < piles; i++) {
|
||||
int size = pool.size();
|
||||
@@ -104,14 +103,11 @@ public class MultiplePilesEffect extends SpellAbilityEffect {
|
||||
source.addRemembered(c);
|
||||
}
|
||||
}
|
||||
final SpellAbility action = AbilityFactory.getAbility(source.getSVar(sa.getParam("ChosenPile")), source);
|
||||
if (sa.isIntrinsic()) {
|
||||
action.setIntrinsic(true);
|
||||
action.changeText();
|
||||
|
||||
AbilitySub sub = sa.getAdditonalAbility("ChosenPile");
|
||||
if (sub != null) {
|
||||
AbilityUtils.resolve(sub);
|
||||
}
|
||||
action.setActivatingPlayer(sa.getActivatingPlayer());
|
||||
((AbilitySub) action).setParent(sa);
|
||||
AbilityUtils.resolve(action);
|
||||
source.clearRemembered();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
package forge.game.ability.effects;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import forge.game.Game;
|
||||
import forge.game.ability.AbilityFactory;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.Card;
|
||||
@@ -35,16 +31,7 @@ public class RepeatEachEffect extends SpellAbilityEffect {
|
||||
public void resolve(SpellAbility sa) {
|
||||
Card source = sa.getHostCard();
|
||||
|
||||
// setup subability to repeat
|
||||
final SpellAbility repeat = AbilityFactory.getAbility(sa.getSVar(sa.getParam("RepeatSubAbility")), source);
|
||||
|
||||
if (sa.isIntrinsic()) {
|
||||
repeat.setIntrinsic(true);
|
||||
repeat.changeText();
|
||||
}
|
||||
|
||||
repeat.setActivatingPlayer(sa.getActivatingPlayer());
|
||||
((AbilitySub) repeat).setParent(sa);
|
||||
AbilitySub repeat = sa.getAdditonalAbility("RepeatSubAbility");
|
||||
|
||||
final Player player = sa.getActivatingPlayer();
|
||||
final Game game = player.getGame();
|
||||
@@ -55,7 +42,7 @@ public class RepeatEachEffect extends SpellAbilityEffect {
|
||||
CardCollectionView repeatCards = null;
|
||||
|
||||
if (sa.hasParam("RepeatCards")) {
|
||||
List<ZoneType> zone = new ArrayList<ZoneType>();
|
||||
List<ZoneType> zone = Lists.newArrayList();
|
||||
if (sa.hasParam("Zone")) {
|
||||
zone = ZoneType.listValueOf(sa.getParam("Zone"));
|
||||
} else {
|
||||
@@ -137,8 +124,7 @@ public class RepeatEachEffect extends SpellAbilityEffect {
|
||||
if (target == null) {
|
||||
target = AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa).get(0);
|
||||
}
|
||||
Set<CounterType> types = new HashSet<CounterType>(target.getCounters().keySet());
|
||||
for (CounterType type : types) {
|
||||
for (CounterType type : target.getCounters().keySet()) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Number$").append(target.getCounters(type));
|
||||
source.setSVar("RepeatSVarCounter", type.getName().toUpperCase());
|
||||
@@ -148,7 +134,7 @@ public class RepeatEachEffect extends SpellAbilityEffect {
|
||||
}
|
||||
if (recordChoice) {
|
||||
boolean random = sa.hasParam("Random");
|
||||
Map<Player, List<Card>> recordMap = new HashMap<Player, List<Card>>();
|
||||
Map<Player, List<Card>> recordMap = Maps.newHashMap();
|
||||
if (sa.hasParam("ChoosePlayer")) {
|
||||
for (Card card : repeatCards) {
|
||||
Player p;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package forge.game.ability.effects;
|
||||
|
||||
import forge.game.Game;
|
||||
import forge.game.ability.AbilityFactory;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.Card;
|
||||
@@ -26,15 +25,7 @@ public class RepeatEffect extends SpellAbilityEffect {
|
||||
Card source = sa.getHostCard();
|
||||
|
||||
// setup subability to repeat
|
||||
final SpellAbility repeat = AbilityFactory.getAbility(sa.getHostCard().getSVar(sa.getParam("RepeatSubAbility")), source);
|
||||
|
||||
if (sa.isIntrinsic()) {
|
||||
repeat.setIntrinsic(true);
|
||||
repeat.changeText();
|
||||
}
|
||||
|
||||
repeat.setActivatingPlayer(sa.getActivatingPlayer());
|
||||
((AbilitySub) repeat).setParent(sa);
|
||||
AbilitySub repeat = sa.getAdditonalAbility("RepeatSubAbility");
|
||||
|
||||
Integer maxRepeat = null;
|
||||
if (sa.hasParam("MaxRepeat")) {
|
||||
@@ -50,11 +41,14 @@ public class RepeatEffect extends SpellAbilityEffect {
|
||||
if (maxRepeat != null && maxRepeat <= count) {
|
||||
// TODO Replace Infinite Loop Break with a game draw. Here are the scenarios that can cause this:
|
||||
// Helm of Obedience vs Graveyard to Library replacement effect
|
||||
|
||||
if(source.getName().equals("Helm of Obedience")) {
|
||||
StringBuilder infLoop = new StringBuilder(sa.getHostCard().toString());
|
||||
infLoop.append(" - To avoid an infinite loop, this repeat has been broken ");
|
||||
infLoop.append(" and the game will now continue in the current state, ending the loop early. ");
|
||||
infLoop.append("Once Draws are available this probably should change to a Draw.");
|
||||
System.out.println(infLoop.toString());
|
||||
}
|
||||
break;
|
||||
}
|
||||
} while (checkRepeatConditions(sa));
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package forge.game.ability.effects;
|
||||
|
||||
import forge.game.ability.AbilityFactory;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.Card;
|
||||
@@ -123,14 +122,11 @@ public class TwoPilesEffect extends SpellAbilityEffect {
|
||||
for (final Card z : chosenPile) {
|
||||
card.addRemembered(z);
|
||||
}
|
||||
final SpellAbility action = AbilityFactory.getAbility(card.getSVar(sa.getParam("ChosenPile")), card);
|
||||
if (sa.isIntrinsic()) {
|
||||
action.setIntrinsic(true);
|
||||
action.changeText();
|
||||
|
||||
AbilitySub sub = sa.getAdditonalAbility("ChosenPile");
|
||||
if (sub != null) {
|
||||
AbilityUtils.resolve(sub);
|
||||
}
|
||||
action.setActivatingPlayer(sa.getActivatingPlayer());
|
||||
((AbilitySub) action).setParent(sa);
|
||||
AbilityUtils.resolve(action);
|
||||
}
|
||||
|
||||
// take action on the unchosen pile
|
||||
@@ -140,14 +136,10 @@ public class TwoPilesEffect extends SpellAbilityEffect {
|
||||
card.addRemembered(z);
|
||||
}
|
||||
|
||||
final SpellAbility action = AbilityFactory.getAbility(card.getSVar(sa.getParam("UnchosenPile")), card);
|
||||
if (sa.isIntrinsic()) {
|
||||
action.setIntrinsic(true);
|
||||
action.changeText();
|
||||
AbilitySub sub = sa.getAdditonalAbility("UnchosenPile");
|
||||
if (sub != null) {
|
||||
AbilityUtils.resolve(sub);
|
||||
}
|
||||
action.setActivatingPlayer(sa.getActivatingPlayer());
|
||||
((AbilitySub) action).setParent(sa);
|
||||
AbilityUtils.resolve(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1846,7 +1846,8 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
sb.append(" (You may pay an additional cost as you cast CARDNAME. If you do, put CARDNAME back into your hand as it resolves.)");
|
||||
sb.append("\r\n");
|
||||
} else if (keyword.startsWith("Entwine")) {
|
||||
final Cost cost = new Cost(keyword.substring(8), false);
|
||||
final String[] n = keyword.split(":");
|
||||
final Cost cost = new Cost(n[1], false);
|
||||
sb.append("Entwine ").append(cost.toSimpleString());
|
||||
sb.append(" (Choose both if you pay the entwine cost.)");
|
||||
sb.append("\r\n");
|
||||
|
||||
@@ -18,8 +18,10 @@
|
||||
package forge.game.card;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
@@ -652,6 +654,17 @@ public class CardFactory {
|
||||
if (from.getSubAbility() != null) {
|
||||
to.setSubAbility(from.getSubAbility().getCopy());
|
||||
}
|
||||
for (Map.Entry<String, AbilitySub> e : from.getAdditonalAbilities().entrySet()) {
|
||||
to.setAdditionalAbility(e.getKey(), e.getValue().getCopy());
|
||||
}
|
||||
for (Map.Entry<String, List<AbilitySub>> e : from.getAdditionalAbilityLists().entrySet()) {
|
||||
to.setAdditionalAbilityList(e.getKey(), Lists.transform(e.getValue(), new Function<AbilitySub, AbilitySub>() {
|
||||
@Override
|
||||
public AbilitySub apply(AbilitySub input) {
|
||||
return input.getCopy();
|
||||
}
|
||||
}));
|
||||
}
|
||||
if (from.getRestrictions() != null) {
|
||||
to.setRestrictions((SpellAbilityRestriction) from.getRestrictions().copy());
|
||||
}
|
||||
|
||||
@@ -2301,6 +2301,9 @@ public class CardFactoryUtil {
|
||||
else if (keyword.startsWith("Emerge")) {
|
||||
addSpellAbility(keyword, card, null);
|
||||
}
|
||||
else if (keyword.startsWith("Entwine")) {
|
||||
addSpellAbility(keyword, card, null);
|
||||
}
|
||||
else if (keyword.startsWith("Escalate")) {
|
||||
addStaticAbility(keyword, card, null);
|
||||
}
|
||||
@@ -3547,6 +3550,24 @@ public class CardFactoryUtil {
|
||||
kws.addSpellAbility(newSA);
|
||||
}
|
||||
card.addSpellAbility(newSA);
|
||||
} else if (keyword.startsWith("Entwine")) {
|
||||
final String[] kw = keyword.split(":");
|
||||
String costStr = kw[1];
|
||||
final SpellAbility sa = card.getFirstSpellAbility();
|
||||
|
||||
final SpellAbility newSA = sa.copy();
|
||||
newSA.getMapParams().put("Secondary", "True");
|
||||
newSA.setBasicSpell(false);
|
||||
newSA.setPayCosts(new Cost(costStr, false).add(sa.getPayCosts()));
|
||||
newSA.addOptionalCost(OptionalCost.Entwine);
|
||||
newSA.setDescription(sa.getDescription() + " (Entwine)");
|
||||
newSA.setStackDescription(""); // Empty StackDescription to rebuild it.
|
||||
if (!intrinsic) {
|
||||
newSA.setTemporary(true);
|
||||
newSA.setIntrinsic(false);
|
||||
kws.addSpellAbility(newSA);
|
||||
}
|
||||
card.addSpellAbility(newSA);
|
||||
} else if (keyword.equals("Epic")) {
|
||||
// Epic does modify existing SA, and does not add new one
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package forge.game.spellability;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
@@ -115,6 +116,9 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
private SpellAbilityRestriction restrictions = new SpellAbilityRestriction();
|
||||
private SpellAbilityCondition conditions = new SpellAbilityCondition();
|
||||
private AbilitySub subAbility = null;
|
||||
|
||||
private Map<String, AbilitySub> additionalAbilities = Maps.newHashMap();
|
||||
private Map<String, List<AbilitySub>> additionalAbilityLists = Maps.newHashMap();
|
||||
|
||||
protected ApiType api = null;
|
||||
|
||||
@@ -204,6 +208,14 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
if (subAbility != null) {
|
||||
subAbility.setHostCard(c);
|
||||
}
|
||||
for (AbilitySub sa : additionalAbilities.values()) {
|
||||
sa.setHostCard(c);
|
||||
}
|
||||
for (List<AbilitySub> list : additionalAbilityLists.values()) {
|
||||
for (AbilitySub sa : list) {
|
||||
sa.setHostCard(c);
|
||||
}
|
||||
}
|
||||
|
||||
view.updateHostCard(this);
|
||||
view.updateDescription(this); //description can change if host card does
|
||||
@@ -310,6 +322,14 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
if (subAbility != null) {
|
||||
subAbility.setActivatingPlayer(player);
|
||||
}
|
||||
for (AbilitySub sa : additionalAbilities.values()) {
|
||||
sa.setActivatingPlayer(player);
|
||||
}
|
||||
for (List<AbilitySub> list : additionalAbilityLists.values()) {
|
||||
for (AbilitySub sa : list) {
|
||||
sa.setActivatingPlayer(player);
|
||||
}
|
||||
}
|
||||
view.updateCanPlay(this);
|
||||
}
|
||||
|
||||
@@ -371,10 +391,6 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
return mapParams.containsKey(key);
|
||||
}
|
||||
|
||||
public void copyParamsToMap(Map<String, String> mapParam) {
|
||||
mapParam.putAll(mapParams);
|
||||
}
|
||||
|
||||
// If this is not null, then ability was made in a factory
|
||||
public ApiType getApi() {
|
||||
return api;
|
||||
@@ -483,6 +499,10 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
return isOptionalCostPaid(OptionalCost.Surge);
|
||||
}
|
||||
|
||||
public boolean isEntwine() {
|
||||
return isOptionalCostPaid(OptionalCost.Entwine);
|
||||
}
|
||||
|
||||
public boolean isOptionalCostPaid(OptionalCost cost) {
|
||||
SpellAbility saRoot = getRootAbility();
|
||||
return saRoot.optionalCosts.contains(cost);
|
||||
@@ -622,6 +642,50 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
}
|
||||
view.updateDescription(this); //description changes when sub-abilities change
|
||||
}
|
||||
|
||||
public Map<String, AbilitySub> getAdditonalAbilities() {
|
||||
return additionalAbilities;
|
||||
}
|
||||
public AbilitySub getAdditonalAbility(final String name) {
|
||||
if (additionalAbilities.containsKey(name)) {
|
||||
return additionalAbilities.get(name);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setAdditionalAbility(final String name, final AbilitySub sa) {
|
||||
if (sa == null) {
|
||||
additionalAbilities.remove(name);
|
||||
} else {
|
||||
sa.setParent(this);
|
||||
additionalAbilities.put(name, sa);
|
||||
}
|
||||
view.updateDescription(this); //description changes when sub-abilities change
|
||||
}
|
||||
|
||||
public Map<String, List<AbilitySub>> getAdditionalAbilityLists() {
|
||||
return additionalAbilityLists;
|
||||
}
|
||||
public List<AbilitySub> getAdditionalAbilityList(final String name) {
|
||||
if (additionalAbilityLists.containsKey(name)) {
|
||||
return additionalAbilityLists.get(name);
|
||||
} else {
|
||||
return ImmutableList.of();
|
||||
}
|
||||
}
|
||||
|
||||
public void setAdditionalAbilityList(final String name, final List<AbilitySub> list) {
|
||||
if (list == null || list.isEmpty()) {
|
||||
additionalAbilityLists.remove(name);
|
||||
} else {
|
||||
List<AbilitySub> result = Lists.newArrayList(list);
|
||||
for (AbilitySub sa : result) {
|
||||
sa.setParent(this);
|
||||
}
|
||||
additionalAbilityLists.put(name, result);
|
||||
}
|
||||
view.updateDescription(this);
|
||||
}
|
||||
public void appendSubAbility(final AbilitySub toAdd) {
|
||||
SpellAbility tailend = this;
|
||||
while (tailend.getSubAbility() != null) {
|
||||
@@ -1450,6 +1514,15 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
if (subAbility != null) {
|
||||
subAbility.changeText();
|
||||
}
|
||||
for (AbilitySub sa : additionalAbilities.values()) {
|
||||
sa.changeText();
|
||||
}
|
||||
|
||||
for (List<AbilitySub> list : additionalAbilityLists.values()) {
|
||||
for (AbilitySub sa : list) {
|
||||
sa.changeText();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1458,6 +1531,14 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
if (subAbility != null) {
|
||||
subAbility.setIntrinsic(i);
|
||||
}
|
||||
for (AbilitySub sa : additionalAbilities.values()) {
|
||||
sa.setIntrinsic(i);
|
||||
}
|
||||
for (List<AbilitySub> list : additionalAbilityLists.values()) {
|
||||
for (AbilitySub sa : list) {
|
||||
sa.setIntrinsic(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SpellAbilityView getView() {
|
||||
|
||||
@@ -244,12 +244,9 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
||||
}
|
||||
}
|
||||
|
||||
if (sp.getApi() == ApiType.Charm) {
|
||||
boolean remember = sp.hasParam("RememberChoice");
|
||||
if (remember) {
|
||||
// Remember the ChoiceName here for later handling
|
||||
source.addRemembered(sp.getSubAbility().getParam("ChoiceName"));
|
||||
}
|
||||
if (sp.getApi() == ApiType.Charm && sp.hasParam("RememberChoice")) {
|
||||
// Remember the Choice here for later handling
|
||||
source.addRemembered(sp.getSubAbility());
|
||||
}
|
||||
|
||||
//cancel auto-pass for all opponents of activating player
|
||||
@@ -618,12 +615,8 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
||||
if (sa == null) {
|
||||
return true;
|
||||
}
|
||||
TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||
if (tgt != null) {
|
||||
int numTargets = sa.getTargets().getNumTargeted();
|
||||
if (tgt.getMinTargets(source, sa) > numTargets || (tgt.getMaxTargets(source, sa) < numTargets)) {
|
||||
return false;
|
||||
}
|
||||
if (!sa.isTargetNumberValid()) {
|
||||
return false;
|
||||
}
|
||||
return hasLegalTargeting(sa.getSubAbility(), source);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user