mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 19:28:01 +00:00
Merge branch 'copyPermWithDifferentNames' into 'master'
CopyPermanentEffect add WithDifferentNames for Choice See merge request core-developers/forge!3700
This commit is contained in:
@@ -1,210 +1 @@
|
|||||||
package forge.game.ability.effects;
|
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.common.base.Predicates;
|
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
|
|
||||||
import forge.StaticData;
|
|
||||||
import forge.card.CardRulesPredicates;
|
|
||||||
import forge.game.Game;
|
|
||||||
import forge.game.ability.AbilityUtils;
|
|
||||||
import forge.game.card.Card;
|
|
||||||
import forge.game.card.CardCollectionView;
|
|
||||||
import forge.game.card.CardFactory;
|
|
||||||
import forge.game.card.CardLists;
|
|
||||||
import forge.game.card.CardZoneTable;
|
|
||||||
import forge.game.event.GameEventCombatChanged;
|
|
||||||
import forge.game.player.Player;
|
|
||||||
import forge.game.spellability.SpellAbility;
|
|
||||||
import forge.game.zone.ZoneType;
|
|
||||||
import forge.item.PaperCard;
|
|
||||||
import forge.util.Aggregates;
|
|
||||||
import forge.util.TextUtil;
|
|
||||||
import forge.util.collect.FCollectionView;
|
|
||||||
import forge.util.PredicateString.StringOp;
|
|
||||||
import forge.util.Localizer;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class CopyPermanentEffect extends TokenEffectBase {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getStackDescription(SpellAbility sa) {
|
|
||||||
if (sa.hasParam("Populate")) {
|
|
||||||
return "Populate. (Create a token that's a copy of a creature token you control.)";
|
|
||||||
}
|
|
||||||
final StringBuilder sb = new StringBuilder();
|
|
||||||
|
|
||||||
|
|
||||||
final List<Card> tgtCards = getTargetCards(sa);
|
|
||||||
|
|
||||||
sb.append("Copy ");
|
|
||||||
sb.append(StringUtils.join(tgtCards, ", "));
|
|
||||||
sb.append(".");
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see forge.card.ability.SpellAbilityEffect#resolve(forge.card.spellability.SpellAbility)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void resolve(final SpellAbility sa) {
|
|
||||||
final Card host = sa.getHostCard();
|
|
||||||
final Player activator = sa.getActivatingPlayer();
|
|
||||||
final Game game = host.getGame();
|
|
||||||
final List<String> pumpKeywords = Lists.newArrayList();
|
|
||||||
|
|
||||||
if (sa.hasParam("Optional")) {
|
|
||||||
if (!activator.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblCopyPermanentConfirm"))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sa.hasParam("PumpKeywords")) {
|
|
||||||
pumpKeywords.addAll(Arrays.asList(sa.getParam("PumpKeywords").split(" & ")));
|
|
||||||
}
|
|
||||||
|
|
||||||
final int numCopies = sa.hasParam("NumCopies") ? AbilityUtils.calculateAmount(host,
|
|
||||||
sa.getParam("NumCopies"), sa) : 1;
|
|
||||||
|
|
||||||
Player controller = null;
|
|
||||||
if (sa.hasParam("Controller")) {
|
|
||||||
final FCollectionView<Player> defined = AbilityUtils.getDefinedPlayers(host, sa.getParam("Controller"), sa);
|
|
||||||
if (!defined.isEmpty()) {
|
|
||||||
controller = defined.getFirst();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (controller == null) {
|
|
||||||
controller = activator;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Card> tgtCards = Lists.newArrayList();
|
|
||||||
|
|
||||||
if (sa.hasParam("ValidSupportedCopy")) {
|
|
||||||
List<PaperCard> cards = Lists.newArrayList(StaticData.instance().getCommonCards().getUniqueCards());
|
|
||||||
String valid = sa.getParam("ValidSupportedCopy");
|
|
||||||
if (valid.contains("X")) {
|
|
||||||
valid = TextUtil.fastReplace(valid,
|
|
||||||
"X", Integer.toString(AbilityUtils.calculateAmount(host, "X", sa)));
|
|
||||||
}
|
|
||||||
if (StringUtils.containsIgnoreCase(valid, "creature")) {
|
|
||||||
Predicate<PaperCard> cpp = Predicates.compose(CardRulesPredicates.Presets.IS_CREATURE, PaperCard.FN_GET_RULES);
|
|
||||||
cards = Lists.newArrayList(Iterables.filter(cards, cpp));
|
|
||||||
}
|
|
||||||
if (StringUtils.containsIgnoreCase(valid, "equipment")) {
|
|
||||||
Predicate<PaperCard> cpp = Predicates.compose(CardRulesPredicates.Presets.IS_EQUIPMENT, PaperCard.FN_GET_RULES);
|
|
||||||
cards = Lists.newArrayList(Iterables.filter(cards, cpp));
|
|
||||||
}
|
|
||||||
if (sa.hasParam("RandomCopied")) {
|
|
||||||
List<PaperCard> copysource = Lists.newArrayList(cards);
|
|
||||||
List<Card> choice = Lists.newArrayList();
|
|
||||||
final String num = sa.hasParam("RandomNum") ? sa.getParam("RandomNum") : "1";
|
|
||||||
int ncopied = AbilityUtils.calculateAmount(host, num, sa);
|
|
||||||
while(ncopied > 0) {
|
|
||||||
final PaperCard cp = Aggregates.random(copysource);
|
|
||||||
Card possibleCard = Card.fromPaperCard(cp, activator); // Need to temporarily set the Owner so the Game is set
|
|
||||||
|
|
||||||
if (possibleCard.isValid(valid, host.getController(), host, sa)) {
|
|
||||||
choice.add(possibleCard);
|
|
||||||
copysource.remove(cp);
|
|
||||||
ncopied -= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tgtCards = choice;
|
|
||||||
} else if (sa.hasParam("DefinedName")) {
|
|
||||||
String name = sa.getParam("DefinedName");
|
|
||||||
if (name.equals("NamedCard")) {
|
|
||||||
if (!host.getNamedCard().isEmpty()) {
|
|
||||||
name = host.getNamedCard();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Predicate<PaperCard> cpp = Predicates.compose(CardRulesPredicates.name(StringOp.EQUALS, name), PaperCard.FN_GET_RULES);
|
|
||||||
cards = Lists.newArrayList(Iterables.filter(cards, cpp));
|
|
||||||
|
|
||||||
if (!cards.isEmpty()) {
|
|
||||||
tgtCards.add(Card.fromPaperCard(cards.get(0), controller));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (sa.hasParam("Choices")) {
|
|
||||||
Player chooser = activator;
|
|
||||||
if (sa.hasParam("Chooser")) {
|
|
||||||
final String choose = sa.getParam("Chooser");
|
|
||||||
chooser = AbilityUtils.getDefinedPlayers(sa.getHostCard(), choose, sa).get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
CardCollectionView choices = game.getCardsIn(ZoneType.Battlefield);
|
|
||||||
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, host);
|
|
||||||
if (!choices.isEmpty()) {
|
|
||||||
String title = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : Localizer.getInstance().getMessage("lblChooseaCard") +" ";
|
|
||||||
|
|
||||||
Card choosen = chooser.getController().chooseSingleEntityForEffect(choices, sa, title, false, null);
|
|
||||||
|
|
||||||
if (choosen != null) {
|
|
||||||
tgtCards.add(choosen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
tgtCards = getDefinedCardsOrTargeted(sa);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean useZoneTable = true;
|
|
||||||
CardZoneTable triggerList = sa.getChangeZoneTable();
|
|
||||||
if (triggerList == null) {
|
|
||||||
triggerList = new CardZoneTable();
|
|
||||||
useZoneTable = false;
|
|
||||||
}
|
|
||||||
if (sa.hasParam("ChangeZoneTable")) {
|
|
||||||
sa.setChangeZoneTable(triggerList);
|
|
||||||
useZoneTable = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
MutableBoolean combatChanged = new MutableBoolean(false);
|
|
||||||
for (final Card c : tgtCards) {
|
|
||||||
// if it only targets player, it already got all needed cards from defined
|
|
||||||
if (sa.usesTargeting() && !sa.getTargetRestrictions().canTgtPlayer() && !c.canBeTargetedBy(sa)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
makeTokens(getProtoType(sa, c), controller, sa, numCopies, true, true, triggerList, combatChanged);
|
|
||||||
} // end foreach Card
|
|
||||||
|
|
||||||
if (!useZoneTable) {
|
|
||||||
triggerList.triggerChangesZoneAll(game);
|
|
||||||
triggerList.clear();
|
|
||||||
}
|
|
||||||
if (combatChanged.isTrue()) {
|
|
||||||
game.updateCombatForView();
|
|
||||||
game.fireEvent(new GameEventCombatChanged());
|
|
||||||
}
|
|
||||||
} // end resolve
|
|
||||||
|
|
||||||
private Card getProtoType(final SpellAbility sa, final Card original) {
|
|
||||||
final Card host = sa.getHostCard();
|
|
||||||
final Player newOwner = sa.getActivatingPlayer();
|
|
||||||
int id = newOwner == null ? 0 : newOwner.getGame().nextCardId();
|
|
||||||
final Card copy = new Card(id, original.getPaperCard(), host.getGame());
|
|
||||||
copy.setOwner(newOwner);
|
|
||||||
copy.setSetCode(original.getSetCode());
|
|
||||||
|
|
||||||
if (sa.hasParam("Embalm")) {
|
|
||||||
copy.setEmbalmed(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sa.hasParam("Eternalize")) {
|
|
||||||
copy.setEternalized(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
copy.setStates(CardFactory.getCloneStates(original, copy, sa));
|
|
||||||
// force update the now set State
|
|
||||||
copy.setState(copy.getCurrentStateName(), true, true);
|
|
||||||
copy.setToken(true);
|
|
||||||
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
10
forge-gui/res/cardsfolder/upcoming/battle_for_bretagard.txt
Normal file
10
forge-gui/res/cardsfolder/upcoming/battle_for_bretagard.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Name:Battle for Bretagard
|
||||||
|
ManaCost:1 G W
|
||||||
|
Types:Enchantment Saga
|
||||||
|
K:Saga:3:TrigToken1,TrigToken2,DBCopy
|
||||||
|
SVar:TrigToken1:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_human_warrior | TokenOwner$ You | SpellDescription$ Create a 1/1 white Human Warrior creature token.
|
||||||
|
SVar:TrigToken2:DB$ Token | TokenAmount$ 1 | TokenScript$ g_1_1_elf_warrior | TokenOwner$ You | SpellDescription$ Create a 1/1 green Elf Warrior creature token.
|
||||||
|
SVar:DBCopy:DB$ CopyPermanent | Choices$ Artifact.token+YouCtrl,Creature.token+YouCtrl | WithDifferentNames$ True | SpellDescription$ Choose any number of artifact tokens and/or creature tokens you control with different names. For each of them, create a token that’s a copy of it.
|
||||||
|
DeckHas:Ability$Token
|
||||||
|
Oracle:(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)\nI — Create a 1/1 white Human Warrior creature token.\nII — Create a 1/1 green Elf Warrior creature token.\nIII — Choose any number of artifact tokens and/or creature tokens you control with different names. For each of them, create a token that’s a copy of it.
|
||||||
|
|
||||||
Reference in New Issue
Block a user