mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 20:28:00 +00:00
@@ -562,7 +562,31 @@ public final class GameActionUtil {
|
||||
|
||||
for (KeywordInterface ki : host.getKeywords()) {
|
||||
final String o = ki.getOriginal();
|
||||
if (o.equals("Conspire")) {
|
||||
if (o.startsWith("Casualty")) {
|
||||
Trigger tr = Iterables.getFirst(ki.getTriggers(), null);
|
||||
if (tr != null) {
|
||||
String n = o.split(":")[1];
|
||||
if (host.wasCast() && n.equals("X")) {
|
||||
n = Integer.toString(pc.announceRequirements(sa, "X for Casualty"));
|
||||
}
|
||||
final String casualtyCost = "Sac<1/Creature.powerGE" + n + "/creature with power " + n +
|
||||
" or greater>";
|
||||
final Cost cost = new Cost(casualtyCost, false);
|
||||
String str = "Pay for Casualty? " + cost.toSimpleString();
|
||||
boolean v = pc.addKeywordCost(sa, cost, ki, str);
|
||||
|
||||
tr.setSVar("Casualty", v ? n : "0");
|
||||
|
||||
if (v) {
|
||||
if (result == null) {
|
||||
result = sa.copy();
|
||||
}
|
||||
result.getPayCosts().add(cost);
|
||||
tr.getOverridingAbility().setSVar("Casualty", n);
|
||||
reset = true;
|
||||
}
|
||||
}
|
||||
} else if (o.equals("Conspire")) {
|
||||
Trigger tr = Iterables.getFirst(ki.getTriggers(), null);
|
||||
if (tr != null) {
|
||||
final String conspireCost = "tapXType<2/Creature.SharesColorWith/" +
|
||||
@@ -807,7 +831,9 @@ public final class GameActionUtil {
|
||||
for (Table.Cell<Long, Long, KeywordsChange> entry : oldKW.cellSet()) {
|
||||
for (KeywordInterface ki : entry.getValue().getKeywords()) {
|
||||
// check if this keyword existed previously
|
||||
if ((ki.getOriginal().startsWith("Replicate") || ki.getOriginal().startsWith("Conspire")) && updatedKW.get(entry.getRowKey(), entry.getColumnKey()) != null) {
|
||||
if ((ki.getOriginal().startsWith("Replicate") || ki.getOriginal().startsWith("Conspire")
|
||||
|| ki.getOriginal().startsWith("Casualty"))
|
||||
&& updatedKW.get(entry.getRowKey(), entry.getColumnKey()) != null) {
|
||||
updatedKW.put(entry.getRowKey(), entry.getColumnKey(), oldKW.get(entry.getRowKey(), entry.getColumnKey()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2095,6 +2095,13 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
|| keyword.startsWith("Renown") || keyword.startsWith("Annihilator") || keyword.startsWith("Devour")) {
|
||||
final String[] k = keyword.split(":");
|
||||
sbLong.append(k[0]).append(" ").append(k[1]).append(" (").append(inst.getReminderText()).append(")");
|
||||
} else if (keyword.startsWith("Casualty")) {
|
||||
final String[] k = keyword.split(":");
|
||||
sbLong.append("Casualty ").append(k[1]);
|
||||
if (k.length >= 4) {
|
||||
sbLong.append(". ").append(k[3]);
|
||||
}
|
||||
sbLong.append(" (").append(inst.getReminderText()).append(")");
|
||||
} else if (keyword.startsWith("Starting intensity")) {
|
||||
sbLong.append(TextUtil.fastReplace(keyword, ":", " "));
|
||||
} else if (keyword.contains("Haunt")) {
|
||||
@@ -2552,12 +2559,16 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
|| keyword.equals("Fuse")) {
|
||||
sbAfter.append(keyword).append(" (").append(inst.getReminderText()).append(")");
|
||||
sbAfter.append("\r\n");
|
||||
} else if (keyword.startsWith("Ripple")) {
|
||||
sbBefore.append(TextUtil.fastReplace(keyword, ":", " ")).append(" (").append(inst.getReminderText()).append(")");
|
||||
sbBefore.append("\r\n");
|
||||
} else if (keyword.startsWith("Dredge")) {
|
||||
sbAfter.append(TextUtil.fastReplace(keyword, ":", " ")).append(" (").append(inst.getReminderText()).append(")");
|
||||
sbAfter.append("\r\n");
|
||||
} else if (keyword.startsWith("Casualty")) {
|
||||
final String[] k = keyword.split(":");
|
||||
sbBefore.append("Casualty ").append(k[1]);
|
||||
if (k.length >= 4) {
|
||||
sbBefore.append(". ").append(k[3]);
|
||||
}
|
||||
sbBefore.append(" (").append(inst.getReminderText()).append(")").append("\r\n\r\n");
|
||||
} else if (keyword.startsWith("Dredge") || keyword.startsWith("Ripple")) {
|
||||
sbAfter.append(TextUtil.fastReplace(keyword, ":", " "));
|
||||
sbAfter.append(" (").append(inst.getReminderText()).append(")").append("\r\n");
|
||||
} else if (keyword.startsWith("Starting intensity")) {
|
||||
sbAfter.append(TextUtil.fastReplace(keyword, ":", " ")).append("\r\n");
|
||||
} else if (keyword.startsWith("Escalate") || keyword.startsWith("Buyback")
|
||||
@@ -3805,6 +3816,10 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
||||
return getCounters(CounterEnumType.LOYALTY);
|
||||
}
|
||||
|
||||
public final void setBaseLoyalty(final int n) {
|
||||
currentState.setBaseLoyalty(Integer.toString(n));
|
||||
}
|
||||
|
||||
// values that are printed on card
|
||||
public final int getBasePower() {
|
||||
return currentState.getBasePower();
|
||||
|
||||
@@ -137,6 +137,10 @@ public class CardFactory {
|
||||
c.setBaseToughness(Integer.parseInt(sourceSA.getParam("CopySetToughness")));
|
||||
}
|
||||
|
||||
if (sourceSA.hasParam("CopySetLoyalty")) {
|
||||
c.setBaseLoyalty(AbilityUtils.calculateAmount(source, sourceSA.getParam("CopySetLoyalty"), sourceSA));
|
||||
}
|
||||
|
||||
if (sourceSA.hasParam("CopyAddTypes")) {
|
||||
c.addType(Arrays.asList(sourceSA.getParam("CopyAddTypes").split(" & ")));
|
||||
}
|
||||
|
||||
@@ -955,6 +955,19 @@ public class CardFactoryUtil {
|
||||
|
||||
inst.addTrigger(parsedTrigger);
|
||||
inst.addTrigger(parsedTrigReturn);
|
||||
} else if (keyword.startsWith("Casualty")) {
|
||||
final String trigScript = "Mode$ SpellCast | ValidCard$ Card.Self | CheckSVar$ Casualty | Secondary$ True";
|
||||
String abString = "DB$ CopySpellAbility | Defined$ TriggeredSpellAbility | Amount$ 1 | MayChooseTarget$ True";
|
||||
String[] k = keyword.split(":");
|
||||
if (k.length > 2) {
|
||||
abString = abString + " | " + k[2];
|
||||
}
|
||||
|
||||
final Trigger casualtyTrigger = TriggerHandler.parseTrigger(trigScript, card, intrinsic);
|
||||
casualtyTrigger.setOverridingAbility(AbilityFactory.getAbility(abString, card));
|
||||
casualtyTrigger.setSVar("Casualty", "0");
|
||||
|
||||
inst.addTrigger(casualtyTrigger);
|
||||
} else if (keyword.equals("Conspire")) {
|
||||
final String trigScript = "Mode$ SpellCast | ValidCard$ Card.Self | CheckSVar$ Conspire | Secondary$ True | TriggerDescription$ Copy CARDNAME if its conspire cost was paid";
|
||||
final String abString = "DB$ CopySpellAbility | Defined$ TriggeredSpellAbility | Amount$ 1 | MayChooseTarget$ True";
|
||||
|
||||
@@ -35,6 +35,7 @@ public enum Keyword {
|
||||
BUSHIDO("Bushido", KeywordWithAmount.class, false, "Whenever this creature blocks or becomes blocked, it gets +%1$d/+%1$d until end of turn."),
|
||||
BUYBACK("Buyback", KeywordWithCost.class, false, "You may pay an additional %s as you cast this spell. If you do, put it into your hand instead of your graveyard as it resolves."),
|
||||
CASCADE("Cascade", SimpleKeyword.class, false, "When you cast this spell, exile cards from the top of your library until you exile a nonland card whose mana value is less than this spell's mana value. You may cast that spell without paying its mana cost if its mana value is less than this spell's mana value. Then put all cards exiled this way that weren't cast on the bottom of your library in a random order."),
|
||||
CASUALTY("Casualty", KeywordWithAmount.class, false, "As you cast this spell, you may sacrifice a creature with power %1$d or greater. When you do, copy this spell."),
|
||||
CHAMPION("Champion", KeywordWithType.class, false, "When this enters the battlefield, sacrifice it unless you exile another %s you control. When this leaves the battlefield, that card returns to the battlefield."),
|
||||
CHANGELING("Changeling", SimpleKeyword.class, true, "This card is every creature type."),
|
||||
CIPHER("Cipher", SimpleKeyword.class, true, "Then you may exile this spell card encoded on a creature you control. Whenever that creature deals combat damage to a player, its controller may cast a copy of the encoded card without paying its mana cost."),
|
||||
|
||||
@@ -28,7 +28,7 @@ public class KeywordWithAmount extends KeywordInstance<KeywordWithAmount> {
|
||||
StringBuilder result = new StringBuilder(
|
||||
String.format(reminderText.replaceAll("\\%(\\d+\\$)?d", "%$1s"), "X")
|
||||
);
|
||||
if (!extra.isEmpty()) {
|
||||
if (!extra.isEmpty() && !extra.contains("$")) {
|
||||
result.insert(result.length()-1, extra);
|
||||
}
|
||||
return result.toString();
|
||||
|
||||
6
forge-gui/res/cardsfolder/upcoming/a_little_chat.txt
Normal file
6
forge-gui/res/cardsfolder/upcoming/a_little_chat.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
Name:A Little Chat
|
||||
ManaCost:1 U
|
||||
Types:Instant
|
||||
K:Casualty:1
|
||||
A:SP$ Dig | DigNum$ 2 | ChangeNum$ 1 | SpellDescription$ Look at the top two cards of your library. Put one of them into your hand and the other on the bottom of your library.
|
||||
Oracle:Casualty 1 (As you cast this spell, you may sacrifice a creature with power 1 or greater. When you do, copy this spell.)\nLook at the top two cards of your library. Put one of them into your hand and the other on the bottom of your library.
|
||||
@@ -0,0 +1,8 @@
|
||||
Name:Anhelo, the Painter
|
||||
ManaCost:U B R
|
||||
Types:Legendary Creature Vampire Assassin
|
||||
K:Deathtouch
|
||||
PT:1/3
|
||||
S:Mode$ Continuous | Affected$ Instant.YouCtrl,Sorcery.YouCtrl | AffectedZone$ Stack | CheckSVar$ X | SVarCompare$ EQ0 | AddKeyword$ Casualty:2 | Description$ The first instant or sorcery spell you cast each turn has casualty 2. (As you cast that spell, you may sacrifice a creature with power 2 or greater. When you do, copy the spell and you may choose new targets for the copy.)
|
||||
SVar:X:Count$ThisTurnCast_Instant.YouCtrl,Sorcery.YouCtrl
|
||||
Oracle:Deathtouch\nThe first instant or sorcery spell you cast each turn has casualty 2. (As you cast that spell, you may sacrifice a creature with power 2 or greater. When you do, copy the spell and you may choose new targets for the copy.)
|
||||
@@ -0,0 +1,9 @@
|
||||
Name:Cut of the Profits
|
||||
ManaCost:X B B
|
||||
Types:Sorcery
|
||||
K:Casualty:3
|
||||
A:SP$ Draw | NumCards$ X | SubAbility$ DBLoseLife | SpellDescription$ You draw X cards and you lose X life.
|
||||
SVar:DBLoseLife:DB$ LoseLife | LifeAmount$ X
|
||||
SVar:X:Count$xPaid
|
||||
DeckHas:Ability$Sacrifice
|
||||
Oracle:Casualty 3 (As you cast this spell, you may sacrifice a creature with power 3 or greater. When you do, copy this spell.)\nYou draw X cards and you lose X life.
|
||||
8
forge-gui/res/cardsfolder/upcoming/cut_your_losses.txt
Normal file
8
forge-gui/res/cardsfolder/upcoming/cut_your_losses.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
Name:Cut Your Losses
|
||||
ManaCost:4 U U
|
||||
Types:Sorcery
|
||||
K:Casualty:2
|
||||
A:SP$ Mill | ValidTgts$ Player | TgtPrompt$ Select target player | NumCards$ X | SpellDescription$ Target player mills half their library, rounded down.
|
||||
SVar:X:TargetedPlayer$CardsInLibrary/HalfDown
|
||||
DeckHas:Ability$Sacrifice|Mill
|
||||
Oracle:Casualty 2 (As you cast this spell, you may sacrifice a creature with power 2 or greater. When you do, copy this spell and you may choose new targets for the copy.)\nTarget player mills half their library, rounded down.
|
||||
8
forge-gui/res/cardsfolder/upcoming/dig_up_the_body.txt
Normal file
8
forge-gui/res/cardsfolder/upcoming/dig_up_the_body.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
Name:Dig Up the Body
|
||||
ManaCost:2 B
|
||||
Types:Instant
|
||||
K:Casualty:1
|
||||
A:SP$ Mill | NumCards$ 2 | SubAbility$ DBReturn | SpellDescription$ Mill two cards,
|
||||
SVar:DBReturn:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | ChangeType$ Creature.YouOwn | Hidden$ True | SpellDescription$ then return a creature card from your graveyard to your hand. (To mill a card, put the top card of your library into your graveyard.)
|
||||
DeckHas:Ability$Graveyard|Mill|Sacrifice
|
||||
Oracle:Casualty 1 (As you cast this spell, you may sacrifice a creature with power 1 or greater. When you do, copy this spell.)\nMill two cards, then return a creature card from your graveyard to your hand. (To mill a card, a player puts the top card of their library into their graveyard.)
|
||||
7
forge-gui/res/cardsfolder/upcoming/illicit_shipment.txt
Normal file
7
forge-gui/res/cardsfolder/upcoming/illicit_shipment.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Name:Illicit Shipment
|
||||
ManaCost:3 B B
|
||||
Types:Sorcery
|
||||
K:Casualty:3
|
||||
A:SP$ ChangeZone | Origin$ Library | Destination$ Hand | NoReveal$ True | ChangeType$ Card | ChangeNum$ 1 | Mandatory$ True | SpellDescription$ Search your library for a card, put that card into your hand, then shuffle.
|
||||
DeckHas:Ability$Sacrifice
|
||||
Oracle:Casualty 3 (As you cast this spell, you may sacrifice a creature with power 3 or greater. When you do, copy this spell and you may choose new targets for the copy.)\nSearch your library for a card, put that card into your hand, then shuffle.
|
||||
7
forge-gui/res/cardsfolder/upcoming/join_the_maestros.txt
Normal file
7
forge-gui/res/cardsfolder/upcoming/join_the_maestros.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Name:Join the Maestros
|
||||
ManaCost:4 B
|
||||
Types:Sorcery
|
||||
K:Casualty:2
|
||||
A:SP$ Token | TokenScript$ b_4_3_ogre_warrior | SpellDescription$ Create a 4/3 black Ogre Warrior creature token.
|
||||
DeckHas:Ability$Sacrifice|Token & Type$Ogre|Warrior
|
||||
Oracle:Casualty 2 (As you cast this spell, you may sacrifice a creature with power 2 or greater. When you do, copy this spell and you may choose new targets for the copy.)\nCreate a 4/3 black Ogre Warrior creature token.
|
||||
7
forge-gui/res/cardsfolder/upcoming/light_em_up.txt
Normal file
7
forge-gui/res/cardsfolder/upcoming/light_em_up.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Name:Light 'Em Up
|
||||
ManaCost:1 R
|
||||
Types:Sorcery
|
||||
K:Casualty:2
|
||||
A:SP$ DealDamage | ValidTgts$ Creature,Planeswalker | TgtPrompt$ Select target creature or planeswalker | NumDmg$ 2 | SpellDescription$ CARDNAME deals 2 damage to target creature or planeswalker.
|
||||
DeckHas:Ability$Sacrifice
|
||||
Oracle:Casualty 2 (As you cast this spell, you may sacrifice a creature with power 2 or greater. When you do, copy this spell and you may choose new targets for the copy.)\nLight 'Em Up deals 2 damage to target creature or planeswalker.
|
||||
7
forge-gui/res/cardsfolder/upcoming/make_disappear.txt
Normal file
7
forge-gui/res/cardsfolder/upcoming/make_disappear.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Name:Make Disappear
|
||||
ManaCost:1 U
|
||||
Types:Instant
|
||||
K:Casualty:1
|
||||
A:SP$ Counter | TargetType$ Spell | TgtPrompt$ Select target spell | ValidTgts$ Card | UnlessCost$ 2 | SpellDescription$ Counter target spell unless its controller pays {2}.
|
||||
DeckHas:Ability$Sacrifice
|
||||
Oracle:Casualty 1 (As you cast this spell, you may sacrifice a creature with power 1 or greater. When you do, copy this spell and you may choose new targets for the copy.)\nCounter target spell unless its controller pays {2}.
|
||||
@@ -0,0 +1,14 @@
|
||||
Name:Ob Nixilis, the Adversary
|
||||
ManaCost:1 B R
|
||||
Types:Legendary Planeswalker Nixilis
|
||||
Loyalty:3
|
||||
K:Casualty:X:NonLegendary$ True | CopySetLoyalty$ Casualty:The copy isn't legendary and has starting loyalty X.
|
||||
A:AB$ RepeatEach | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | RepeatPlayers$ Opponent | RepeatSubAbility$ DBDrain | SubAbility$ DBGainLife | SpellDescription$ Each opponent loses 2 life unless they discard a card. If you control a Demon or Devil, you gain 2 life.
|
||||
SVar:DBDrain:DB$ LoseLife | Defined$ Player.IsRemembered | LifeAmount$ 2 | UnlessCost$ Discard<1/Card> | UnlessPayer$ Player.IsRemembered
|
||||
SVar:DBGainLife:DB$ GainLife | LifeAmount$ 2 | ConditionPresent$ Demon.YouCtrl,Devil.YouCtrl | StackDescription$ None
|
||||
A:AB$ Token | Cost$ SubCounter<2/LOYALTY> | TokenScript$ r_1_1_devil_burn | Planeswalker$ True | SpellDescription$ Create a 1/1 red Devil creature token with "When this creature dies, it deals 1 damage to any target."
|
||||
A:AB$ Draw | Cost$ SubCounter<7/LOYALTY> | Planeswalker$ True | Ultimate$ True | ValidTgts$ Player | TgtPrompt$ Select target player | NumCards$ 7 | SubAbility$ DBLoseLife | SpellDescription$ Target player draws seven cards and loses 7 life.
|
||||
SVar:DBLoseLife:DB$ LoseLife | LifeAmount$ 7 | Defined$ Targeted
|
||||
DeckHas:Ability$Sacrifice|LifeGain|Token & Type$Devil
|
||||
DeckHints:Type$Demon|Devil
|
||||
Oracle:Casualty X. The copy isn't legendary and has starting loyalty X. (As you cast this spell, you may sacrifice a creature with power X. When you do, copy this spell and you may choose new targets for the copy.)\n[+1]: Each opponent loses 2 life unless they discard a card. If you control a Demon or Devil, you gain 2 life.\n[−2]: Create a 1/1 red Devil creature token with "When this creature dies, it deals 1 damage to any target."\n[−7]: Target player draws seven cards and loses 7 life.
|
||||
10
forge-gui/res/cardsfolder/upcoming/rob_the_archives.txt
Normal file
10
forge-gui/res/cardsfolder/upcoming/rob_the_archives.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
Name:Rob the Archives
|
||||
ManaCost:1 R
|
||||
Types:Sorcery
|
||||
K:Casualty:1
|
||||
A:SP$ Dig | DigNum$ 2 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBEffect | SpellDescription$ Exile the top two cards of your library. You may play those cards this turn.
|
||||
SVar:DBEffect:DB$ Effect | StaticAbilities$ MayPlay | RememberObjects$ Remembered | ForgetOnMoved$ Exile | SubAbility$ DBCleanup | StackDescription$ They may play those cards this turn.
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
SVar:MayPlay:Mode$ Continuous | Affected$ Card.IsRemembered | EffectZone$ Command | AffectedZone$ Exile | MayPlay$ True | Description$ You may play those cards this turn.
|
||||
DeckHas:Ability$Sacrifice
|
||||
Oracle:Casualty 1 (As you cast this spell, you may sacrifice a creature with power 1 or greater. When you do, copy this spell.)\nExile the top two cards of your library. You may play those cards this turn.
|
||||
9
forge-gui/res/cardsfolder/upcoming/rooftop_nuisance.txt
Normal file
9
forge-gui/res/cardsfolder/upcoming/rooftop_nuisance.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
Name:Rooftop Nuisance
|
||||
ManaCost:2 U
|
||||
Types:Sorcery
|
||||
K:Casualty:1
|
||||
A:SP$ Tap | ValidTgts$ Creature | SubAbility$ DBPump | SpellDescription$ Tap target creature. It doesn't untap during its controller's next untap step.
|
||||
SVar:DBPump:DB$ Pump | Defined$ Targeted | KW$ HIDDEN This card doesn't untap during your next untap step. | Duration$ Permanent | SubAbility$ DBDraw | SpellDescription$ It doesn't untap during its controller's next untap step.
|
||||
SVar:DBDraw:DB$ Draw | NumCards$ 1 | SpellDescription$ Draw a card.
|
||||
DeckHas:Ability$Sacrifice
|
||||
Oracle:Casualty 1 (As you cast this spell, you may sacrifice a creature with power 1 or greater. When you do, copy this spell and you may choose new targets for the copy.)\nTap target creature. It doesn't untap during its controller's next untap step.\nDraw a card.
|
||||
6
forge-gui/res/tokenscripts/b_4_3_ogre_warrior.txt
Normal file
6
forge-gui/res/tokenscripts/b_4_3_ogre_warrior.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
Name:Ogre Warrior Token
|
||||
ManaCost:no cost
|
||||
Types:Creature Ogre Warrior
|
||||
Colors:black
|
||||
PT:4/3
|
||||
Oracle:
|
||||
Reference in New Issue
Block a user