mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 12:48:00 +00:00
Discord, Lord of Disharmony + Support (#5073)
* Discord, Lord of Disharmony + Support * Prevent AI use for now. * Include chosen name's description in text box * Clean up DescriptionFromChosenName * Remove blank lines from Discord card script --------- Co-authored-by: Jetz <Jetz722@gmail.com>
This commit is contained in:
@@ -19,6 +19,7 @@ import forge.game.spellability.SpellAbility;
|
|||||||
import forge.game.spellability.SpellAbilityPredicates;
|
import forge.game.spellability.SpellAbilityPredicates;
|
||||||
import forge.game.spellability.TargetChoices;
|
import forge.game.spellability.TargetChoices;
|
||||||
import forge.game.staticability.StaticAbility;
|
import forge.game.staticability.StaticAbility;
|
||||||
|
import forge.game.staticability.StaticAbilityCastWithFlash;
|
||||||
import forge.game.trigger.Trigger;
|
import forge.game.trigger.Trigger;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.util.Expressions;
|
import forge.util.Expressions;
|
||||||
@@ -388,6 +389,34 @@ public class ForgeScript {
|
|||||||
if (sa.isManaAbilityFor(paidFor, colorCanUse)) {
|
if (sa.isManaAbilityFor(paidFor, colorCanUse)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else if(property.equals("NamedSpell")) {
|
||||||
|
boolean found = false;
|
||||||
|
for (String name : source.getNamedCards()) {
|
||||||
|
if (sa.cardState.getName().equals(name)) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
else if (property.equals("CouldCastTiming")) {
|
||||||
|
Card host = sa.getHostCard();
|
||||||
|
Game game = host.getGame();
|
||||||
|
if (game.getStack().isSplitSecondOnStack()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Adapted from SpellAbility.canCastTiming, to determine if the SA could be cast at the current timing (assuming the controller had priority).
|
||||||
|
|
||||||
|
if (sourceController.canCastSorcery() || sa.getRestrictions().isInstantSpeed()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (sa.isSpell()) {
|
||||||
|
return host.isInstant() || host.hasKeyword(Keyword.FLASH) || StaticAbilityCastWithFlash.anyWithFlash(sa, host, sourceController);
|
||||||
|
}
|
||||||
|
if (sa.isActivatedAbility()) {
|
||||||
|
return !sa.isPwAbility() && !sa.getRestrictions().isSorcerySpeed();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
} else if (sa.getHostCard() != null) {
|
} else if (sa.getHostCard() != null) {
|
||||||
return sa.getHostCard().hasProperty(property, sourceController, source, spellAbility);
|
return sa.getHostCard().hasProperty(property, sourceController, source, spellAbility);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,16 +160,23 @@ public class PlayEffect extends SpellAbilityEffect {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (sa.hasParam("CopyFromChosenName")) {
|
} else if (sa.hasParam("CopyFromChosenName")) {
|
||||||
String name = controller.getNamedCard();
|
String name = source.getNamedCard();
|
||||||
if (name.trim().isEmpty()) return;
|
if (name.trim().isEmpty()) {
|
||||||
|
name = controller.getNamedCard();
|
||||||
|
if(name.trim().isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
Card card = Card.fromPaperCard(StaticData.instance().getCommonCards().getUniqueByName(name), controller);
|
Card card = Card.fromPaperCard(StaticData.instance().getCommonCards().getUniqueByName(name), controller);
|
||||||
// so it gets added to stack
|
// so it gets added to stack
|
||||||
card.setCopiedPermanent(card);
|
card.setCopiedPermanent(card);
|
||||||
|
// Keeps adventures from leaving the recast effect
|
||||||
|
card.setCopiedSpell(true);
|
||||||
card.setToken(true);
|
card.setToken(true);
|
||||||
tgtCards = new CardCollection(card);
|
tgtCards = new CardCollection(card);
|
||||||
} else {
|
} else {
|
||||||
tgtCards = new CardCollection();
|
tgtCards = new CardCollection();
|
||||||
// filter only cards that didn't changed zones
|
// filter only cards that didn't change zones
|
||||||
for (Card c : getTargetCards(sa)) {
|
for (Card c : getTargetCards(sa)) {
|
||||||
Card gameCard = game.getCardState(c, null);
|
Card gameCard = game.getCardState(c, null);
|
||||||
if (c.equalsWithGameTimestamp(gameCard)) {
|
if (c.equalsWithGameTimestamp(gameCard)) {
|
||||||
@@ -280,6 +287,7 @@ public class PlayEffect extends SpellAbilityEffect {
|
|||||||
tgtCard.setZone(zone);
|
tgtCard.setZone(zone);
|
||||||
// to fix the CMC
|
// to fix the CMC
|
||||||
tgtCard.setCopiedPermanent(original);
|
tgtCard.setCopiedPermanent(original);
|
||||||
|
tgtCard.setCopiedSpell(true);
|
||||||
if (zone != null) {
|
if (zone != null) {
|
||||||
zone.add(tgtCard);
|
zone.add(tgtCard);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2824,6 +2824,21 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
sAbility = sbSA.toString();
|
sAbility = sbSA.toString();
|
||||||
} else if (sa.isSpell() && sa.isBasicSpell()) {
|
} else if (sa.isSpell() && sa.isBasicSpell()) {
|
||||||
continue;
|
continue;
|
||||||
|
} else if (sa.hasParam("DescriptionFromChosenName") && !getNamedCard().isEmpty()) {
|
||||||
|
String name = getNamedCard();
|
||||||
|
ICardFace namedFace = StaticData.instance().getCommonCards().getFaceByName(name);
|
||||||
|
StringBuilder sbSA = new StringBuilder(sAbility);
|
||||||
|
sbSA.append(linebreak);
|
||||||
|
sbSA.append(Localizer.getInstance().getMessage("lblSpell"));
|
||||||
|
sbSA.append(" — ");
|
||||||
|
if(!namedFace.getManaCost().isNoCost()) {
|
||||||
|
sbSA.append(namedFace.getManaCost().getSimpleString()).append(": ");
|
||||||
|
}
|
||||||
|
sbSA.append(namedFace.getName()).append("\r\n");
|
||||||
|
sbSA.append(namedFace.getType()).append("\r\n");
|
||||||
|
sbSA.append(namedFace.getOracleText().replaceAll("\\\\n", "\r\n"));
|
||||||
|
sbSA.append(linebreak);
|
||||||
|
sAbility = sbSA.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sa.getManaPart() != null) {
|
if (sa.getManaPart() != null) {
|
||||||
|
|||||||
19
forge-gui/res/cardsfolder/d/discord_lord_of_disharmony.txt
Normal file
19
forge-gui/res/cardsfolder/d/discord_lord_of_disharmony.txt
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
Name:Discord, Lord of Disharmony
|
||||||
|
ManaCost:2 B R
|
||||||
|
Types:Legendary Creature Chimera
|
||||||
|
PT:3/5
|
||||||
|
K:Flying
|
||||||
|
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ ChooseName | TriggerDescription$ At the beginning of your end step, choose a random nonland Magic card name. Until your next end step, you may cast a copy of a spell with that name, and mana of any type can be spent to cast it. If you cast a spell this way, copy this ability if NICKNAME is on the battlefield.
|
||||||
|
SVar:ChooseName:DB$ NameCard | ValidCards$ Card.nonLand | Defined$ You | AtRandom$ True | SubAbility$ CreateAbility
|
||||||
|
SVar:CreateAbility:DB$ Effect | Abilities$ DiscordCast | Triggers$ TrigHostLeaves | Duration$ UntilYourNextEndStep | ImprintCards$ OriginalHost.inZoneBattlefield | SubAbility$ CleanupName
|
||||||
|
SVar:CleanupName:DB$ Cleanup | ClearNamedCard$ True
|
||||||
|
SVar:DiscordCast:ST$ Play | ActivationZone$ Command | Cost$ 0 | CopyFromChosenName$ True | ManaConversion$ AnyType->AnyColor | ValidSA$ Spell.CouldCastTiming+NamedSpell | Optional$ True | RememberPlayed$ True | SubAbility$ CheckCast | DescriptionFromChosenName$ True | SpellDescription$ Cast a copy of the spell with the chosen name. If NICKNAME is on the battlefield, copy its ability.
|
||||||
|
SVar:WasCast:Remembered$Valid Card
|
||||||
|
SVar:CheckCast:DB$ Branch | BranchConditionSVar$ WasCast | TrueSubAbility$ ExileAbility
|
||||||
|
SVar:ExileAbility:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile | SubAbility$ CleanupMemory
|
||||||
|
SVar:CleanupMemory:DB$ Cleanup | ClearRemembered$ True | ClearNamedCard$ True | SubAbility$ MaybeRepeat
|
||||||
|
SVar:MaybeRepeat:DB$ ImmediateTrigger | ConditionPresent$ Card | ConditionDefined$ Imprinted | Execute$ ChooseName | TriggerDescription$ Choose a random nonland Magic card name. Until your next end step, you may cast a copy of a spell with that name, and mana of any type can be spent to cast it. If you cast a spell this way, copy this ability if NICKNAME is on the battlefield.
|
||||||
|
SVar:TrigHostLeaves:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | Static$ True | ValidCard$ Card.IsImprinted | TriggerZones$ Command | Execute$ OnHostLost
|
||||||
|
SVar:OnHostLost:DB$ Cleanup | ClearImprinted$ True
|
||||||
|
AI:RemoveDeck:All
|
||||||
|
Oracle:Flying\nAt the beginning of your end step, choose a random nonland Magic card name. Until your next end step, you may cast a copy of a spell with that name, and mana of any type can be spent to cast it. If you cast a spell this way, copy this ability if Discord is on the battlefield.
|
||||||
Reference in New Issue
Block a user