Ghostly Dancers and support

This commit is contained in:
tool4EvEr
2024-10-11 20:35:45 +02:00
committed by Chris H
parent 9568abc6f4
commit 036e6ec1bf
8 changed files with 52 additions and 25 deletions

View File

@@ -155,7 +155,7 @@ public class SetStateAi extends SpellAbilityAi {
}
// non-permanent facedown can't be turned face up
if (!card.getRules().getType().isPermanent()) {
if (!card.getRules().getType().isPermanent() || !card.canBeTurnedFaceUp()) {
return false;
}
} else {

View File

@@ -285,7 +285,16 @@ public final class AbilityFactory {
final String key = "Choices";
if (mapParams.containsKey(key)) {
List<String> names = Lists.newArrayList(mapParams.get(key).split(","));
spellAbility.setAdditionalAbilityList(key, Lists.transform(names, input -> getSubAbility(state, input, sVarHolder)));
spellAbility.setAdditionalAbilityList(key, Lists.transform(names, input -> {
AbilitySub sub = getSubAbility(state, input, sVarHolder);
if (api == ApiType.GenericChoice) {
// support scripters adding restrictions to filter illegal choices
sub.setRestrictions(new SpellAbilityRestriction());
makeRestrictions(sub);
}
return sub;
}
));
}
}

View File

@@ -21,15 +21,6 @@ public class VillainousChoiceEffect extends SpellAbilityEffect {
for (Player p : getDefinedPlayersOrTargeted(sa)) {
int choiceAmount = p.getAdditionalVillainousChoices() + 1;
List<SpellAbility> saToRemove = Lists.newArrayList();
for (SpellAbility saChoice : abilities) {
if (saChoice.getRestrictions() != null && !saChoice.getRestrictions().checkOtherRestrictions(sa.getHostCard(), saChoice, sa.getActivatingPlayer())) {
saToRemove.add(saChoice);
}
}
abilities.removeAll(saToRemove);
// For the AI chooseSAForEffect really should take the least good ability. Currently it just takes the first
List<SpellAbility> chosenSAs = Lists.newArrayList();
for(int i = 0; i < choiceAmount; i++) {

View File

@@ -805,6 +805,11 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
return setState(CardStateName.FaceDown, false);
}
public boolean canBeTurnedFaceUp() {
Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(this);
return !getGame().getReplacementHandler().cantHappenCheck(ReplacementType.TurnFaceUp, repParams);
}
public void forceTurnFaceUp() {
turnFaceUp(false, null);
}
@@ -813,14 +818,10 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
return turnFaceUp(true, cause);
}
public boolean turnFaceUp(boolean runTriggers, SpellAbility cause) {
if (!isFaceDown()) {
if (!isFaceDown() || !canBeTurnedFaceUp()) {
return false;
}
// Check replacement effects
Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(this);
if (game.getReplacementHandler().cantHappenCheck(ReplacementType.TurnFaceUp, repParams)) return false;
CardCollectionView cards = hasMergedCard() ? getMergedCards() : new CardCollection(this);
boolean retResult = false;
long ts = game.getNextTimestamp();
@@ -855,10 +856,9 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
triggerHandler.registerActiveTrigger(this, false);
}
if (runTriggers) {
// Run replacement effects
Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(this);
game.getReplacementHandler().run(ReplacementType.TurnFaceUp, repParams);
// Run triggers
final Map<AbilityKey, Object> runParams = AbilityKey.mapFromCard(this);
runParams.put(AbilityKey.Cause, cause);

View File

@@ -1924,6 +1924,18 @@ public class CardProperty {
if (!card.isGoaded()) {
return false;
}
} else if (property.equals("FullyUnlocked")) {
if (card.getUnlockedRooms().size() < 2) {
return false;
}
} else if (property.startsWith("canReceiveCounters")) {
if (!card.canReceiveCounters(CounterType.getType(property.split(" ")[1]))) {
return false;
}
} else if (property.equals("canBeTurnedFaceUp")) {
if (!card.canBeTurnedFaceUp()) {
return false;
}
} else if (property.equals("NoAbilities")) {
if (!card.hasNoAbilities()) {
return false;

View File

@@ -18,12 +18,8 @@
package forge.game.spellability;
import forge.card.mana.ManaCost;
import forge.game.ability.AbilityKey;
import forge.game.card.Card;
import forge.game.cost.Cost;
import forge.game.replacement.ReplacementType;
import java.util.Map;
/**
* <p>
@@ -58,9 +54,8 @@ public abstract class AbilityStatic extends Ability implements Cloneable {
// Check if ability can't be attempted because of replacement effect
// Initial usage is Karlov Watchdog preventing disguise/morph/cloak/manifest turning face up
if (this.isTurnFaceUp()) {
Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(c);
if (c.getGame().getReplacementHandler().cantHappenCheck(ReplacementType.TurnFaceUp, repParams)) return false;
if (this.isTurnFaceUp() && !c.canBeTurnedFaceUp()) {
return false;
}
return this.getRestrictions().canPlay(c, this);

View File

@@ -0,0 +1,13 @@
Name:Ghostly Dancers
ManaCost:3 W W
Types:Creature Spirit
PT:2/5
K:Flying
T:Mode$ ChangesZone | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigChoice | TriggerDescription$ When CARDNAME enters, return an enchantment card from your graveyard to your hand or unlock a locked door of a Room you control.
SVar:TrigChoice:DB$ GenericChoice | Choices$ DBReturn,DBUnlock
SVar:DBReturn:DB$ ChangeZone | Hidden$ True | Mandatory$ True | ChangeType$ Enchantment.YouOwn | Origin$ Graveyard | Destination$ Hand | IsPresent$ Enchantment.YouOwn | PresentZone$ Graveyard | SpellDescription$ Return an enchantment card from your graveyard to your hand
SVar:DBUnlock:DB$ UnlockDoor | Mode$ Unlock | Choices$ Room.YouCtrl+!FullyUnlocked | IsPresent$ Room.YouCtrl+!FullyUnlocked | SpellDescription$ Unlock a locked door of a Room you control
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, create a 3/1 white Spirit creature token with flying.
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigToken | TriggerZones$ Battlefield | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, create a 3/1 white Spirit creature token with flying.
SVar:TrigToken:DB$ Token | TokenScript$ w_3_1_spirit_flying
Oracle:Flying\nWhen Ghostly Dancers enters, return an enchantment card from your graveyard to your hand or unlock a locked door of a Room you control.\nEerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, create a 3/1 white Spirit creature token with flying.

View File

@@ -0,0 +1,7 @@
Name:Spirit Token
ManaCost:no cost
Types:Creature Spirit
Colors:white
PT:3/1
K:Flying
Oracle:Flying