Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Allow objects to have multiple names #12839

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 24 additions & 60 deletions Mage.Sets/src/mage/cards/d/DetentionSphere.java
Original file line number Diff line number Diff line change
@@ -1,36 +1,37 @@
package mage.cards.d;

import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ReturnFromExileForSourceEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.common.FilterNonlandPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.NamePredicate;
import mage.game.ExileZone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.util.CardUtil;
import org.apache.log4j.Logger;

import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

/**
* @author LevelX2
*/
public final class DetentionSphere extends CardImpl {

static final protected FilterPermanent filter = new FilterNonlandPermanent("nonland permanent not named Detention Sphere");
private static final FilterPermanent filter = new FilterNonlandPermanent("nonland permanent not named Detention Sphere");

static {
filter.add(Predicates.not(new NamePredicate("Detention Sphere")));
Expand All @@ -48,7 +49,7 @@ public DetentionSphere(UUID ownerId, CardSetInfo setInfo) {

// When Detention Sphere leaves the battlefield, return the exiled
// cards to the battlefield under their owner's control.
this.addAbility(new LeavesBattlefieldTriggeredAbility(new DetentionSphereLeavesEffect(), false));
this.addAbility(new LeavesBattlefieldTriggeredAbility(new ReturnFromExileForSourceEffect(Zone.BATTLEFIELD), false));
}

private DetentionSphere(final DetentionSphere card) {
Expand All @@ -65,7 +66,8 @@ class DetentionSphereEntersEffect extends OneShotEffect {

DetentionSphereEntersEffect() {
super(Outcome.Exile);
staticText = "you may exile target nonland permanent not named Detention Sphere and all other permanents with the same name as that permanent";
staticText = "exile target nonland permanent not named Detention Sphere " +
"and all other permanents with the same name as that permanent";
}

private DetentionSphereEntersEffect(final DetentionSphereEntersEffect effect) {
Expand All @@ -74,65 +76,27 @@ private DetentionSphereEntersEffect(final DetentionSphereEntersEffect effect) {

@Override
public boolean apply(Game game, Ability source) {
UUID exileId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
Permanent targetPermanent = game.getPermanent(getTargetPointer().getFirst(game, source));
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = game.getObject(source);
if (sourceObject != null && exileId != null && targetPermanent != null && controller != null) {

if (CardUtil.haveEmptyName(targetPermanent)) { // face down creature
controller.moveCardToExileWithInfo(targetPermanent, exileId, sourceObject.getIdName(), source, game, Zone.BATTLEFIELD, true);
} else {
String name = targetPermanent.getName();
for (Permanent permanent : game.getBattlefield().getActivePermanents(source.getControllerId(), game)) {
if (permanent != null && CardUtil.haveSameNames(permanent, name, game)) {
controller.moveCardToExileWithInfo(permanent, exileId, sourceObject.getIdName(), source, game, Zone.BATTLEFIELD, true);
}
}
}
return true;
Player player = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (player == null || permanent == null) {
return false;
}
return false;
Set<Card> permanents = game
.getBattlefield()
.getActivePermanents(StaticFilters.FILTER_PERMANENT, source.getControllerId(), source, game)
.stream()
.filter(p -> p.sharesName(permanent, game))
.collect(Collectors.toSet());
permanents.add(permanent);
return player.moveCardsToExile(
permanents, source, game, true,
CardUtil.getExileZoneId(game, source),
CardUtil.getSourceName(game, source)
);
}

@Override
public DetentionSphereEntersEffect copy() {
return new DetentionSphereEntersEffect(this);
}
}

class DetentionSphereLeavesEffect extends OneShotEffect {

DetentionSphereLeavesEffect() {
super(Outcome.Neutral);
staticText = "return the exiled cards to the battlefield under their owner's control";
}

private DetentionSphereLeavesEffect(final DetentionSphereLeavesEffect effect) {
super(effect);
}

@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = source.getSourceObject(game);
if (sourceObject != null && controller != null) {
Permanent permanentLeftBattlefield = (Permanent) getValue("permanentLeftBattlefield");
if (permanentLeftBattlefield == null) {
Logger.getLogger(ReturnFromExileForSourceEffect.class).error("Permanent not found: " + sourceObject.getName());
return false;
}
ExileZone exile = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source.getSourceId(), permanentLeftBattlefield.getZoneChangeCounter(game)));
if (exile != null) {
controller.moveCards(exile.getCards(game), Zone.BATTLEFIELD, source, game, false, false, true, null);
}
return true;
}
return false;
}

@Override
public DetentionSphereLeavesEffect copy() {
return new DetentionSphereLeavesEffect(this);
}
}
13 changes: 1 addition & 12 deletions Mage.Sets/src/mage/cards/g/GrimoireThief.java
Original file line number Diff line number Diff line change
Expand Up @@ -200,18 +200,7 @@ public boolean apply(Game game, Ability source) {
for (Iterator<StackObject> iterator = game.getStack().iterator(); iterator.hasNext(); ) {
StackObject stackObject = iterator.next();
MageObject mageObject = game.getObject(card.getId());
String name1;
String name2;
if (mageObject instanceof SplitCard) {
name1 = ((SplitCard) mageObject).getLeftHalfCard().getName();
name2 = ((SplitCard) mageObject).getRightHalfCard().getName();
} else {
// modal double faces cards, adventure cards -- all have one name in non stack/battlefield zone
name1 = mageObject.getName();
name2 = name1;
}

if (CardUtil.haveSameNames(stackObject, name1, game) || CardUtil.haveSameNames(stackObject, name2, game)) {
if (stackObject.sharesName(mageObject, game)) {
Spell spell = (Spell) stackObject;
game.getStack().counter(stackObject.getId(), source, game);
game.informPlayers(sourceObject.getLogName() + ": spell " + spell.getIdName() + " was countered.");
Expand Down
45 changes: 17 additions & 28 deletions Mage.Sets/src/mage/cards/r/ReflectorMage.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
import mage.util.CardUtil;

import java.util.Objects;
import java.util.UUID;

/**
Expand Down Expand Up @@ -59,7 +57,8 @@ class ReflectorMageEffect extends OneShotEffect {

ReflectorMageEffect() {
super(Outcome.Benefit);
this.staticText = "return target creature an opponent controls to its owner's hand. That creature's owner can't cast spells with the same name as that creature until your next turn";
this.staticText = "return target creature an opponent controls to its owner's hand. " +
"That creature's owner can't cast spells with the same name as that creature until your next turn";
}

private ReflectorMageEffect(final ReflectorMageEffect effect) {
Expand All @@ -74,35 +73,31 @@ public ReflectorMageEffect copy() {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Permanent targetCreature = game.getPermanent(getTargetPointer().getFirst(game, source));
if (targetCreature != null) {
controller.moveCards(targetCreature, Zone.HAND, source, game);
if (!CardUtil.haveEmptyName(targetCreature)) { // if the creature had no name, no restrict effect will be created
game.addEffect(new ExclusionRitualReplacementEffect(targetCreature.getName(), targetCreature.getOwnerId()), source);
}
}
return true;
Permanent targetCreature = game.getPermanent(getTargetPointer().getFirst(game, source));
if (controller == null || targetCreature == null) {
return false;
}
return false;
controller.moveCards(targetCreature, Zone.HAND, source, game);
game.addEffect(new ReflectorMageReplacementEffect(targetCreature, targetCreature.getOwnerId()), source);
return true;
}
}

class ExclusionRitualReplacementEffect extends ContinuousRuleModifyingEffectImpl {
class ReflectorMageReplacementEffect extends ContinuousRuleModifyingEffectImpl {

private final String creatureName;
private final Permanent creature;
private final UUID ownerId;

ExclusionRitualReplacementEffect(String creatureName, UUID ownerId) {
ReflectorMageReplacementEffect(Permanent creature, UUID ownerId) {
super(Duration.UntilYourNextTurn, Outcome.Detriment);
staticText = "That creature's owner can't cast spells with the same name as that creature until your next turn";
this.creatureName = creatureName;
this.creature = creature.copy();
this.ownerId = ownerId;
}

private ExclusionRitualReplacementEffect(final ExclusionRitualReplacementEffect effect) {
private ReflectorMageReplacementEffect(final ReflectorMageReplacementEffect effect) {
super(effect);
this.creatureName = effect.creatureName;
this.creature = effect.creature.copy();
this.ownerId = effect.ownerId;
}

Expand All @@ -114,18 +109,12 @@ public boolean checksEventType(GameEvent event, Game game) {
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
SpellAbility spellAbility = SpellAbility.getSpellAbilityFromEvent(event, game);
if (spellAbility == null) {
return false;
}
Card card = spellAbility.getCharacteristics(game);
if (card == null) {
return false;
}
return CardUtil.haveSameNames(card, creatureName, game) && Objects.equals(ownerId, card.getOwnerId());
return spellAbility != null && card != null && card.isOwnedBy(ownerId) && card.sharesName(creature, game);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to null check spell ability before calling getCharacteristics

}

@Override
public ExclusionRitualReplacementEffect copy() {
return new ExclusionRitualReplacementEffect(this);
public ReflectorMageReplacementEffect copy() {
return new ReflectorMageReplacementEffect(this);
}
}
Loading
Loading