mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 18:58:00 +00:00
MH1 Slice onto instance or sorcery
This commit is contained in:
committed by
Michael Kamensky
parent
6ea96baf0a
commit
3644b8f74f
@@ -76,7 +76,6 @@ public class ComputerUtil {
|
||||
source.setSplitStateToPlayAbility(sa);
|
||||
|
||||
if (sa.isSpell() && !source.isCopiedSpell()) {
|
||||
if (source.getType().hasStringType("Arcane")) {
|
||||
sa = AbilityUtils.addSpliceEffects(sa);
|
||||
if (sa.getSplicedCards() != null && !sa.getSplicedCards().isEmpty() && ai.getController().isAI()) {
|
||||
// we need to reconsider and retarget the SA after additional SAs have been added onto it via splice,
|
||||
@@ -88,7 +87,6 @@ public class ComputerUtil {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
source.setCastSA(sa);
|
||||
sa.setLastStateBattlefield(game.getLastStateBattlefield());
|
||||
|
||||
@@ -17,6 +17,7 @@ import forge.game.GameObject;
|
||||
import forge.game.ability.AbilityFactory.AbilityRecordType;
|
||||
import forge.game.card.*;
|
||||
import forge.game.cost.Cost;
|
||||
import forge.game.keyword.Keyword;
|
||||
import forge.game.keyword.KeywordInterface;
|
||||
import forge.game.mana.ManaConversionMatrix;
|
||||
import forge.game.mana.ManaCostBeingPaid;
|
||||
@@ -1843,10 +1844,23 @@ public class AbilityUtils {
|
||||
final Card source = sa.getHostCard();
|
||||
final Player player = sa.getActivatingPlayer();
|
||||
|
||||
final CardCollection splices = CardLists.filter(player.getCardsIn(ZoneType.Hand), new Predicate<Card>() {
|
||||
final CardCollectionView hand = player.getCardsIn(ZoneType.Hand);
|
||||
|
||||
if (hand.isEmpty()) {
|
||||
return sa;
|
||||
}
|
||||
|
||||
final CardCollection splices = CardLists.filter(hand, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(Card input) {
|
||||
return input.hasStartOfKeyword("Splice");
|
||||
for (final KeywordInterface inst : input.getKeywords(Keyword.SPLICE)) {
|
||||
String k = inst.getOriginal();
|
||||
final String n[] = k.split(":");
|
||||
if (source.isValid(n[1].split(","), player, input, sa)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1871,13 +1885,12 @@ public class AbilityUtils {
|
||||
|
||||
public static void addSpliceEffect(final SpellAbility sa, final Card c) {
|
||||
Cost spliceCost = null;
|
||||
for (final KeywordInterface inst : c.getKeywords()) {
|
||||
// This Function thinks that Splice exist only once on the card
|
||||
for (final KeywordInterface inst : c.getKeywords(Keyword.SPLICE)) {
|
||||
final String k = inst.getOriginal();
|
||||
if (k.startsWith("Splice")) {
|
||||
final String n[] = k.split(":");
|
||||
spliceCost = new Cost(n[2], false);
|
||||
}
|
||||
}
|
||||
|
||||
if (spliceCost == null)
|
||||
return;
|
||||
|
||||
@@ -2198,7 +2198,22 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
} else if (keyword.startsWith("Splice")) {
|
||||
final String[] n = keyword.split(":");
|
||||
final Cost cost = new Cost(n[2], false);
|
||||
sbAfter.append("Splice onto ").append(n[1]).append(" ").append(cost.toSimpleString());
|
||||
|
||||
String desc;
|
||||
|
||||
if (n.length > 3) {
|
||||
desc = n[3];
|
||||
} else {
|
||||
String k[] = n[1].split(",");
|
||||
for (int i = 0; i < k.length; i++) {
|
||||
if (CardType.isACardType(k[i])) {
|
||||
k[i] = k[i].toLowerCase();
|
||||
}
|
||||
}
|
||||
desc = StringUtils.join(k, " or ");
|
||||
}
|
||||
|
||||
sbAfter.append("Splice onto ").append(desc).append(" ").append(cost.toSimpleString());
|
||||
sbAfter.append(" (" + inst.getReminderText() + ")").append("\r\n");
|
||||
} else if (keyword.equals("Storm")) {
|
||||
sbAfter.append("Storm (");
|
||||
@@ -4236,7 +4251,14 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
return getAmountOfKeyword(k, currentState);
|
||||
}
|
||||
public final int getAmountOfKeyword(final Keyword k, CardState state) {
|
||||
return state.getCachedKeyword(k).size();
|
||||
return getKeywords(k, state).size();
|
||||
}
|
||||
|
||||
public final Collection<KeywordInterface> getKeywords(final Keyword k) {
|
||||
return getKeywords(k, currentState);
|
||||
}
|
||||
public final Collection<KeywordInterface> getKeywords(final Keyword k, CardState state) {
|
||||
return state.getCachedKeyword(k);
|
||||
}
|
||||
|
||||
// This is for keywords with a number like Bushido, Annihilator and Rampage.
|
||||
@@ -4254,7 +4276,7 @@ public class Card extends GameEntity implements Comparable<Card> {
|
||||
*/
|
||||
public final int getKeywordMagnitude(final Keyword k, CardState state) {
|
||||
int count = 0;
|
||||
for (final KeywordInterface inst : state.getCachedKeyword(k)) {
|
||||
for (final KeywordInterface inst : getKeywords(k, state)) {
|
||||
String kw = inst.getOriginal();
|
||||
// this can't be used yet for everything because of X values in Bushido X
|
||||
// KeywordInterface#getAmount
|
||||
|
||||
@@ -4435,9 +4435,7 @@ public class CardFactoryUtil {
|
||||
sb.append(" | CostDesc$ ").append(ManaCostParser.parse(manacost));
|
||||
sb.append("| Origin$ Library | Destination$ Hand |");
|
||||
sb.append("ChangeType$ ").append(type);
|
||||
// no Keyword.getReminderText, it does not work yet
|
||||
sb.append(" | SpellDescription$ (Search your library for a ").append(desc).append(" card, reveal it,");
|
||||
sb.append(" and put it into your hand. Then shuffle your library.)");
|
||||
sb.append(" | SpellDescription$ (").append(inst.getReminderText()).append(")");
|
||||
|
||||
SpellAbility sa = AbilityFactory.getAbility(sb.toString(), card);
|
||||
sa.setIsCycling(true);
|
||||
|
||||
@@ -18,6 +18,8 @@ import forge.game.keyword.KeywordInterface;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.item.PaperToken;
|
||||
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
@@ -231,7 +233,7 @@ public class TokenInfo {
|
||||
final Card host = sa.getHostCard();
|
||||
final Game game = host.getGame();
|
||||
|
||||
String edition = host.getSetCode();
|
||||
String edition = ObjectUtils.firstNonNull(sa.getOriginalHost(), host).getSetCode();
|
||||
PaperToken token = StaticData.instance().getAllTokens().getToken(script, edition);
|
||||
|
||||
if (token != null) {
|
||||
|
||||
@@ -1,20 +1,38 @@
|
||||
package forge.game.keyword;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import forge.card.CardType;
|
||||
import forge.game.cost.Cost;
|
||||
|
||||
public class KeywordWithCostAndType extends KeywordInstance<KeywordWithCostAndType> {
|
||||
private Cost cost;
|
||||
private String type;
|
||||
private String strType = null;
|
||||
|
||||
@Override
|
||||
protected void parse(String details) {
|
||||
final String[] k = details.split(":");
|
||||
type = k[0];
|
||||
cost = new Cost(k[1], false);
|
||||
if (k.length > 2) {
|
||||
strType = k[2];
|
||||
} else {
|
||||
String n[] = type.split(",");
|
||||
for (int i = 0; i < n.length; i++) {
|
||||
if (CardType.isACardType(n[i])) {
|
||||
n[i] = n[i].toLowerCase();
|
||||
} else if (n[i].equals("Basic")) {
|
||||
n[i] = "basic land";
|
||||
}
|
||||
}
|
||||
|
||||
strType = StringUtils.join(n, " or ");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String formatReminderText(String reminderText) {
|
||||
return String.format(reminderText, cost.toSimpleString(), type);
|
||||
return String.format(reminderText, cost.toSimpleString(), strType);
|
||||
}
|
||||
}
|
||||
|
||||
7
forge-gui/res/cardsfolder/upcoming/everdream.txt
Normal file
7
forge-gui/res/cardsfolder/upcoming/everdream.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Name:Everdream
|
||||
ManaCost:1 U
|
||||
Types:Instant
|
||||
K:Splice:Instant,Sorcery:2 U
|
||||
A:SP$ Draw | Cost$ 1 U | NumCards$ 1 | SpellDescription$ Draw a card.
|
||||
AI:RemoveDeck:Random
|
||||
Oracle:Draw a card.\nSplice onto instant or sorcery {2}{U} (As you cast an instant or sorcery spell, you may reveal this card from your hand and pay its splice cost. If you do, add this card's effects to that spell.)
|
||||
7
forge-gui/res/cardsfolder/upcoming/splicers_skill.txt
Normal file
7
forge-gui/res/cardsfolder/upcoming/splicers_skill.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Name:Splicer's Skill
|
||||
ManaCost:2 W
|
||||
Types:Sorcery
|
||||
K:Splice:Instant,Sorcery:3 W
|
||||
A:SP$ Token | Cost$ 2 W | TokenAmount$ 1 | TokenScript$ c_3_3_a_golem | TokenOwner$ You | LegacyImage$ c 3 3 a golem mh1 | SpellDescription$ Create a 3/3 colorless Golem artifact creature token.
|
||||
AI:RemoveDeck:Random
|
||||
Oracle:Create a 3/3 colorless Golem artifact creature token.\nSplice onto instant or sorcery {3}{W} (As you cast an instant or sorcery spell, you may reveal this card from your hand and pay its splice cost. If you do, add this card's effects to that spell.)
|
||||
@@ -325,6 +325,7 @@ c_2_2_pincher_5dn.jpg https://downloads.cardforge.org/images/tokens/c_2_2_pinche
|
||||
c_2_2_a_spawn_dst.jpg https://downloads.cardforge.org/images/tokens/c_2_2_a_spawn_dst.jpg
|
||||
c_2_2_a_spawn_td2.jpg https://downloads.cardforge.org/images/tokens/c_2_2_a_spawn_td2.jpg
|
||||
c_3_2_eldrazi_horror_emn.jpg https://downloads.cardforge.org/images/tokens/c_3_2_eldrazi_horror_emn.jpg
|
||||
c_3_3_a_golem_mh1.jpg https://downloads.cardforge.org/images/tokens/c_3_3_a_golem_mh1.jpg
|
||||
c_3_3_a_golem_mm2.jpg https://downloads.cardforge.org/images/tokens/c_3_3_a_golem_mm2.jpg
|
||||
c_3_3_a_golem_mm3.jpg https://downloads.cardforge.org/images/tokens/c_3_3_a_golem_mm3.jpg
|
||||
c_3_3_a_golem_nph.jpg https://downloads.cardforge.org/images/tokens/c_3_3_a_golem_nph.jpg
|
||||
|
||||
@@ -85,9 +85,7 @@ public class HumanPlay {
|
||||
CharmEffect.makeChoices(sa);
|
||||
}
|
||||
|
||||
if (sa.isSpell() && source.getType().hasStringType("Arcane")) {
|
||||
sa = AbilityUtils.addSpliceEffects(sa);
|
||||
}
|
||||
|
||||
if (sa.hasParam("Bestow")) {
|
||||
source.animateBestow();
|
||||
@@ -199,10 +197,8 @@ public class HumanPlay {
|
||||
if (sa.getApi() == ApiType.Charm && !sa.isWrapper()) {
|
||||
CharmEffect.makeChoices(sa);
|
||||
}
|
||||
if (sa.isSpell() && source.getType().hasStringType("Arcane")) {
|
||||
sa = AbilityUtils.addSpliceEffects(sa);
|
||||
}
|
||||
}
|
||||
final CostPayment payment = new CostPayment(sa.getPayCosts(), sa);
|
||||
|
||||
final HumanPlaySpellAbility req = new HumanPlaySpellAbility(controller, sa, payment);
|
||||
|
||||
@@ -71,7 +71,7 @@ public abstract class ImageFetcher {
|
||||
final String filename = imageKey.substring(2) + ".jpg";
|
||||
String tokenUrl = tokenImages.get(filename);
|
||||
if (tokenUrl == null) {
|
||||
System.err.println("No specified file.. Attempting to download from default Url");
|
||||
System.err.println("No specified file for '" + filename + "'.. Attempting to download from default Url");
|
||||
tokenUrl = String.format("%s%s", ForgeConstants.URL_TOKEN_DOWNLOAD, filename);
|
||||
}
|
||||
destFile = new File(ForgeConstants.CACHE_TOKEN_PICS_DIR, filename);
|
||||
|
||||
Reference in New Issue
Block a user