mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 19:28:01 +00:00
make TokenDoubler use new Replacement Effect
This commit is contained in:
@@ -51,6 +51,7 @@ public abstract class GameState {
|
|||||||
|
|
||||||
public abstract IPaperCard getPaperCard(String cardName);
|
public abstract IPaperCard getPaperCard(String cardName);
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append(String.format("humanlife=%d\n", humanLife));
|
sb.append(String.format("humanlife=%d\n", humanLife));
|
||||||
@@ -269,9 +270,7 @@ public abstract class GameState {
|
|||||||
Card c;
|
Card c;
|
||||||
if (cardinfo[0].startsWith("t:")) {
|
if (cardinfo[0].startsWith("t:")) {
|
||||||
String tokenStr = cardinfo[0].substring(2);
|
String tokenStr = cardinfo[0].substring(2);
|
||||||
// TODO: Use a version of the API that doesn't return a list (i.e. these shouldn't be affected
|
c = CardFactory.makeOneToken(CardFactory.TokenInfo.fromString(tokenStr), player);
|
||||||
// by doubling season, etc).
|
|
||||||
c = CardFactory.makeToken(CardFactory.TokenInfo.fromString(tokenStr), player).get(0);
|
|
||||||
} else {
|
} else {
|
||||||
c = Card.fromPaperCard(getPaperCard(cardinfo[0]), player);
|
c = Card.fromPaperCard(getPaperCard(cardinfo[0]), player);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -438,16 +438,16 @@ public class TokenAi extends SpellAbilityAi {
|
|||||||
final String imageName = imageNames.get(MyRandom.getRandom().nextInt(imageNames.size()));
|
final String imageName = imageNames.get(MyRandom.getRandom().nextInt(imageNames.size()));
|
||||||
final CardFactory.TokenInfo tokenInfo = new CardFactory.TokenInfo(substitutedName, imageName,
|
final CardFactory.TokenInfo tokenInfo = new CardFactory.TokenInfo(substitutedName, imageName,
|
||||||
cost, substitutedTypes, tokenKeywords, finalPower, finalToughness);
|
cost, substitutedTypes, tokenKeywords, finalPower, finalToughness);
|
||||||
List<Card> tokens = CardFactory.makeToken(tokenInfo, ai);
|
Card token = CardFactory.makeOneToken(tokenInfo, ai);
|
||||||
if (tokens.isEmpty()) {
|
|
||||||
|
if (token == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final Card c = tokens.get(0);
|
|
||||||
|
|
||||||
// Grant rule changes
|
// Grant rule changes
|
||||||
if (tokenHiddenKeywords != null) {
|
if (tokenHiddenKeywords != null) {
|
||||||
for (final String s : tokenHiddenKeywords) {
|
for (final String s : tokenHiddenKeywords) {
|
||||||
c.addHiddenExtrinsicKeyword(s);
|
token.addHiddenExtrinsicKeyword(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -455,8 +455,8 @@ public class TokenAi extends SpellAbilityAi {
|
|||||||
if (tokenAbilities != null) {
|
if (tokenAbilities != null) {
|
||||||
for (final String s : tokenAbilities) {
|
for (final String s : tokenAbilities) {
|
||||||
final String actualAbility = host.getSVar(s);
|
final String actualAbility = host.getSVar(s);
|
||||||
final SpellAbility grantedAbility = AbilityFactory.getAbility(actualAbility, c);
|
final SpellAbility grantedAbility = AbilityFactory.getAbility(actualAbility, token);
|
||||||
c.addSpellAbility(grantedAbility);
|
token.addSpellAbility(grantedAbility);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -464,10 +464,10 @@ public class TokenAi extends SpellAbilityAi {
|
|||||||
if (tokenTriggers != null) {
|
if (tokenTriggers != null) {
|
||||||
for (final String s : tokenTriggers) {
|
for (final String s : tokenTriggers) {
|
||||||
final String actualTrigger = host.getSVar(s);
|
final String actualTrigger = host.getSVar(s);
|
||||||
final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, c, true);
|
final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, token, true);
|
||||||
final String ability = host.getSVar(parsedTrigger.getMapParams().get("Execute"));
|
final String ability = host.getSVar(parsedTrigger.getMapParams().get("Execute"));
|
||||||
parsedTrigger.setOverridingAbility(AbilityFactory.getAbility(ability, c));
|
parsedTrigger.setOverridingAbility(AbilityFactory.getAbility(ability, token));
|
||||||
c.addTrigger(parsedTrigger);
|
token.addTrigger(parsedTrigger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -481,7 +481,7 @@ public class TokenAi extends SpellAbilityAi {
|
|||||||
name = actualSVar.split(":")[0];
|
name = actualSVar.split(":")[0];
|
||||||
actualSVar = actualSVar.split(":")[1];
|
actualSVar = actualSVar.split(":")[1];
|
||||||
}
|
}
|
||||||
c.setSVar(name, actualSVar);
|
token.setSVar(name, actualSVar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,18 +489,18 @@ public class TokenAi extends SpellAbilityAi {
|
|||||||
if (tokenStaticAbilities != null) {
|
if (tokenStaticAbilities != null) {
|
||||||
for (final String s : tokenStaticAbilities) {
|
for (final String s : tokenStaticAbilities) {
|
||||||
final String actualAbility = host.getSVar(s);
|
final String actualAbility = host.getSVar(s);
|
||||||
c.addStaticAbilityString(actualAbility);
|
token.addStaticAbilityString(actualAbility);
|
||||||
c.addStaticAbility(actualAbility);
|
token.addStaticAbility(actualAbility);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply static abilities and prune dead tokens
|
// Apply static abilities and prune dead tokens
|
||||||
final Game game = ai.getGame();
|
final Game game = ai.getGame();
|
||||||
ComputerUtilCard.applyStaticContPT(game, c, null);
|
ComputerUtilCard.applyStaticContPT(game, token, null);
|
||||||
if (!notNull && c.getNetToughness() < 1) {
|
if (!notNull && token.getNetToughness() < 1) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return c;
|
return token;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -191,9 +191,7 @@ public class GameCopier {
|
|||||||
private Card createCardCopy(Game newGame, Player newOwner, Card c) {
|
private Card createCardCopy(Game newGame, Player newOwner, Card c) {
|
||||||
if (c.isToken() && !c.isEmblem()) {
|
if (c.isToken() && !c.isEmblem()) {
|
||||||
String tokenStr = new CardFactory.TokenInfo(c).toString();
|
String tokenStr = new CardFactory.TokenInfo(c).toString();
|
||||||
// TODO: Use a version of the API that doesn't return a list (i.e. these shouldn't be affected
|
return CardFactory.makeOneToken(CardFactory.TokenInfo.fromString(tokenStr), newOwner);
|
||||||
// by doubling season, etc).
|
|
||||||
return CardFactory.makeToken(CardFactory.TokenInfo.fromString(tokenStr), newOwner).get(0);
|
|
||||||
}
|
}
|
||||||
if (USE_FROM_PAPER_CARD && !c.isEmblem()) {
|
if (USE_FROM_PAPER_CARD && !c.isEmblem()) {
|
||||||
return Card.fromPaperCard(c.getPaperCard(), newOwner);
|
return Card.fromPaperCard(c.getPaperCard(), newOwner);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ 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;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
import forge.StaticData;
|
import forge.StaticData;
|
||||||
import forge.card.CardRulesPredicates;
|
import forge.card.CardRulesPredicates;
|
||||||
@@ -32,7 +33,6 @@ import forge.util.PredicateString.StringOp;
|
|||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -59,11 +59,11 @@ public class CopyPermanentEffect extends SpellAbilityEffect {
|
|||||||
public void resolve(final SpellAbility sa) {
|
public void resolve(final SpellAbility sa) {
|
||||||
final Card hostCard = sa.getHostCard();
|
final Card hostCard = sa.getHostCard();
|
||||||
final Game game = hostCard.getGame();
|
final Game game = hostCard.getGame();
|
||||||
final List<String> keywords = new ArrayList<String>();
|
final List<String> keywords = Lists.newArrayList();
|
||||||
final List<String> types = new ArrayList<String>();
|
final List<String> types = Lists.newArrayList();
|
||||||
final List<String> svars = new ArrayList<String>();
|
final List<String> svars = Lists.newArrayList();
|
||||||
final List<String> triggers = new ArrayList<String>();
|
final List<String> triggers = Lists.newArrayList();
|
||||||
final List<String> pumpKeywords = new ArrayList<String>();
|
final List<String> pumpKeywords = Lists.newArrayList();
|
||||||
|
|
||||||
final long timestamp = game.getNextTimestamp();
|
final long timestamp = game.getNextTimestamp();
|
||||||
|
|
||||||
@@ -119,8 +119,8 @@ public class CopyPermanentEffect extends SpellAbilityEffect {
|
|||||||
cards = Lists.newArrayList(Iterables.filter(cards, cpp));
|
cards = Lists.newArrayList(Iterables.filter(cards, cpp));
|
||||||
}
|
}
|
||||||
if (sa.hasParam("RandomCopied")) {
|
if (sa.hasParam("RandomCopied")) {
|
||||||
List<PaperCard> copysource = new ArrayList<PaperCard>(cards);
|
List<PaperCard> copysource = Lists.newArrayList(cards);
|
||||||
List<Card> choice = new ArrayList<Card>();
|
List<Card> choice = Lists.newArrayList();
|
||||||
final String num = sa.hasParam("RandomNum") ? sa.getParam("RandomNum") : "1";
|
final String num = sa.hasParam("RandomNum") ? sa.getParam("RandomNum") : "1";
|
||||||
int ncopied = AbilityUtils.calculateAmount(hostCard, num, sa);
|
int ncopied = AbilityUtils.calculateAmount(hostCard, num, sa);
|
||||||
while(ncopied > 0) {
|
while(ncopied > 0) {
|
||||||
@@ -156,8 +156,26 @@ public class CopyPermanentEffect extends SpellAbilityEffect {
|
|||||||
for (final Card c : tgtCards) {
|
for (final Card c : tgtCards) {
|
||||||
if ((tgt == null) || c.canBeTargetedBy(sa)) {
|
if ((tgt == null) || c.canBeTargetedBy(sa)) {
|
||||||
|
|
||||||
int multiplier = numCopies * hostCard.getController().getTokenDoublersMagnitude();
|
int multiplier = numCopies;
|
||||||
final List<Card> crds = new ArrayList<Card>(multiplier);
|
|
||||||
|
final Map<String, Object> repParams = Maps.newHashMap();
|
||||||
|
repParams.put("Event", "CreateToken");
|
||||||
|
repParams.put("Affected", controller);
|
||||||
|
repParams.put("TokenNum", multiplier);
|
||||||
|
repParams.put("EffectOnly", true);
|
||||||
|
|
||||||
|
switch (game.getReplacementHandler().run(repParams)) {
|
||||||
|
case NotReplaced:
|
||||||
|
break;
|
||||||
|
case Updated: {
|
||||||
|
multiplier = (int) repParams.get("TokenNum");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<Card> crds = Lists.newArrayListWithCapacity(multiplier);
|
||||||
|
|
||||||
for (int i = 0; i < multiplier; i++) {
|
for (int i = 0; i < multiplier; i++) {
|
||||||
final Card copy = CardFactory.copyCopiableCharacteristics(c, sa.getActivatingPlayer());
|
final Card copy = CardFactory.copyCopiableCharacteristics(c, sa.getActivatingPlayer());
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import com.google.common.base.Function;
|
|||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
import forge.ImageKeys;
|
import forge.ImageKeys;
|
||||||
import forge.StaticData;
|
import forge.StaticData;
|
||||||
@@ -797,9 +798,33 @@ public class CardFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static List<Card> makeToken(final TokenInfo tokenInfo, final Player controller) {
|
public static List<Card> makeToken(final TokenInfo tokenInfo, final Player controller) {
|
||||||
|
return makeToken(tokenInfo, controller, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Card> makeToken(final TokenInfo tokenInfo, final Player controller, final boolean applyMultiplier) {
|
||||||
final List<Card> list = Lists.newArrayList();
|
final List<Card> list = Lists.newArrayList();
|
||||||
final Card c = tokenInfo.toCard(controller.getGame());
|
final Game game = controller.getGame();
|
||||||
final int multiplier = controller.getTokenDoublersMagnitude();
|
final Card c = tokenInfo.toCard(game);
|
||||||
|
|
||||||
|
int multiplier = 1;
|
||||||
|
|
||||||
|
final Map<String, Object> repParams = Maps.newHashMap();
|
||||||
|
repParams.put("Event", "CreateToken");
|
||||||
|
repParams.put("Affected", controller);
|
||||||
|
repParams.put("TokenNum", multiplier);
|
||||||
|
repParams.put("EffectOnly", applyMultiplier);
|
||||||
|
|
||||||
|
switch (game.getReplacementHandler().run(repParams)) {
|
||||||
|
case NotReplaced:
|
||||||
|
break;
|
||||||
|
case Updated: {
|
||||||
|
multiplier = (int) repParams.get("TokenNum");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < multiplier; i++) {
|
for (int i = 0; i < multiplier; i++) {
|
||||||
Card temp = i == 0 ? c : copyStats(c, controller);
|
Card temp = i == 0 ? c : copyStats(c, controller);
|
||||||
|
|
||||||
@@ -814,6 +839,22 @@ public class CardFactory {
|
|||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Card makeOneToken(final TokenInfo info, final Player controller) {
|
||||||
|
|
||||||
|
final Game game = controller.getGame();
|
||||||
|
final Card c = info.toCard(game);
|
||||||
|
|
||||||
|
for (final String kw : info.intrinsicKeywords) {
|
||||||
|
c.addIntrinsicKeyword(kw);
|
||||||
|
}
|
||||||
|
|
||||||
|
c.setOwner(controller);
|
||||||
|
c.setToken(true);
|
||||||
|
CardFactoryUtil.parseKeywords(c, c.getName());
|
||||||
|
CardFactoryUtil.setupKeywordedAbilities(c);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy triggered ability
|
* Copy triggered ability
|
||||||
|
|||||||
@@ -2563,11 +2563,6 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
return CardLists.getColor(getCardsIn(ZoneType.Battlefield), color);
|
return CardLists.getColor(getCardsIn(ZoneType.Battlefield), color);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTokenDoublersMagnitude() {
|
|
||||||
int tokenDoublers = keywords.getAmount("TokenDoubler");
|
|
||||||
return 1 << tokenDoublers; // pow(a,0) = 1; pow(a,1) = a
|
|
||||||
}
|
|
||||||
|
|
||||||
public final int getAmountOfKeyword(final String k) {
|
public final int getAmountOfKeyword(final String k) {
|
||||||
return keywords.getAmount(k);
|
return keywords.getAmount(k);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user