use of mage.abilities.Mode in project mage by magefree.
the class SpellskiteEffect method apply.
@Override
public boolean apply(Game game, Ability source) {
StackObject stackObject = game.getStack().getStackObject(source.getFirstTarget());
MageObject sourceObject = game.getObject(source.getSourceId());
if (stackObject != null && sourceObject != null) {
Targets targets = new Targets();
Ability sourceAbility;
String oldTargetName = null;
if (stackObject instanceof Spell) {
Spell spell = (Spell) stackObject;
sourceAbility = spell.getSpellAbility();
} else if (stackObject instanceof StackAbility) {
StackAbility stackAbility = (StackAbility) stackObject;
sourceAbility = stackAbility;
} else {
return false;
}
for (UUID modeId : sourceAbility.getModes().getSelectedModes()) {
Mode mode = sourceAbility.getModes().get(modeId);
targets.addAll(mode.getTargets());
}
boolean twoTimesTarget = false;
if (targets.size() == 1 && targets.get(0).getTargets().size() == 1) {
Target target = targets.get(0);
if (target.getFirstTarget().equals(source.getSourceId())) {
// Target was already the same source, so no change / target event to create
return true;
}
if (target.canTarget(stackObject.getControllerId(), source.getSourceId(), sourceAbility, game)) {
oldTargetName = getTargetName(targets.getFirstTarget(), game);
target.clearChosen();
// The source is still the spell on the stack
target.addTarget(source.getSourceId(), stackObject.getStackAbility(), game);
}
} else {
// needed for targeted source's with multiple targets
Player controller = game.getPlayer(source.getControllerId());
boolean validTargets = false;
do {
for (Target target : targets) {
if (target.getTargets().contains(source.getSourceId())) {
// You can't change a traget to Spellskite, if Spellskite is already targeted by this target
continue;
}
for (UUID targetId : target.getTargets()) {
String name = getTargetName(targetId, game);
if (target.canTarget(stackObject.getControllerId(), source.getSourceId(), sourceAbility, game)) {
validTargets = true;
if (name != null && controller.chooseUse(Outcome.Neutral, "Change target from " + name + " to " + sourceObject.getLogName() + '?', source, game)) {
oldTargetName = getTargetName(targetId, game);
int damageAmount = target.getTargetAmount(targetId);
target.remove(targetId);
// The source is still the spell on the stack
// add the source permanent id and set the damage if any
target.addTarget(source.getSourceId(), stackObject.getStackAbility(), game);
target.setTargetAmount(source.getSourceId(), damageAmount, game);
break;
}
}
}
if (oldTargetName != null) {
break;
}
}
if (oldTargetName == null) {
game.informPlayer(controller, "You have to select at least one target to change to " + sourceObject.getIdName() + '!');
}
} while (validTargets && oldTargetName == null);
}
if (oldTargetName != null) {
game.informPlayers(sourceObject.getLogName() + ": Changed target of " + stackObject.getLogName() + " from " + oldTargetName + " to " + sourceObject.getLogName());
} else if (twoTimesTarget) {
game.informPlayers(sourceObject.getLogName() + ": Target not changed to " + sourceObject.getLogName() + " because its not valid to target it twice for " + stackObject.getLogName());
} else {
game.informPlayers(sourceObject.getLogName() + ": Target not changed to " + sourceObject.getLogName() + " because its no valid target for " + stackObject.getLogName());
}
return true;
}
return false;
}
use of mage.abilities.Mode in project mage by magefree.
the class DackFaydenEmblemEffect method checkTrigger.
@Override
public boolean checkTrigger(GameEvent event, Game game) {
boolean returnValue = false;
List<UUID> targetedPermanentIds = new ArrayList<>(0);
Player player = game.getPlayer(this.getControllerId());
if (player != null) {
if (event.getPlayerId().equals(this.getControllerId())) {
Spell spell = game.getStack().getSpell(event.getTargetId());
if (spell != null) {
SpellAbility spellAbility = spell.getSpellAbility();
for (Mode mode : spellAbility.getModes().values()) {
for (Target target : mode.getTargets()) {
if (!target.isNotTarget()) {
for (UUID targetId : target.getTargets()) {
if (game.getBattlefield().containsPermanent(targetId)) {
returnValue = true;
targetedPermanentIds.add(targetId);
}
}
}
}
}
for (Effect effect : spellAbility.getEffects()) {
for (UUID targetId : effect.getTargetPointer().getTargets(game, spellAbility)) {
if (game.getBattlefield().containsPermanent(targetId)) {
returnValue = true;
targetedPermanentIds.add(targetId);
}
}
}
}
}
}
for (Effect effect : this.getEffects()) {
if (effect instanceof DackFaydenEmblemEffect) {
DackFaydenEmblemEffect dackEffect = (DackFaydenEmblemEffect) effect;
List<Permanent> permanents = new ArrayList<>();
for (UUID permanentId : targetedPermanentIds) {
Permanent permanent = game.getPermanent(permanentId);
if (permanent != null) {
permanents.add(permanent);
}
}
dackEffect.setTargets(permanents, game);
}
}
return returnValue;
}
use of mage.abilities.Mode in project mage by magefree.
the class StackObjectImpl method chooseNewTargets.
/**
* 114.6. Some effects allow a player to change the target(s) of a spell or
* ability, and other effects allow a player to choose new targets for a
* spell or ability.
* <p>
* 114.6a If an effect allows a player to "change the target(s)" of a spell
* or ability, each target can be changed only to another legal target. If a
* target can't be changed to another legal target, the original target is
* unchanged, even if the original target is itself illegal by then. If all
* the targets aren't changed to other legal targets, none of them are
* changed.
* <p>
* 114.6b If an effect allows a player to "change a target" of a spell or
* ability, the process described in rule 114.6a is followed, except that
* only one of those targets may be changed (rather than all of them or none
* of them).
* <p>
* 114.6c If an effect allows a player to "change any targets" of a spell or
* ability, the process described in rule 114.6a is followed, except that
* any number of those targets may be changed (rather than all of them or
* none of them).
* <p>
* 114.6d If an effect allows a player to "choose new targets" for a spell
* or ability, the player may leave any number of the targets unchanged,
* even if those targets would be illegal. If the player chooses to change
* some or all of the targets, the new targets must be legal and must not
* cause any unchanged targets to become illegal.
* <p>
* 114.6e When changing targets or choosing new targets for a spell or
* ability, only the final set of targets is evaluated to determine whether
* the change is legal.
* <p>
* Example: Arc Trail is a sorcery that reads "Arc Trail deals 2 damage to
* any target and 1 damage to another target creature or player." The
* current targets of Arc Trail are Runeclaw Bear and Llanowar Elves, in
* that order. You cast Redirect, an instant that reads "You may choose new
* targets for target spell," targeting Arc Trail. You can change the first
* target to Llanowar Elves and change the second target to Runeclaw Bear.
* <p>
* 114.7. Modal spells and abilities may have different targeting
* requirements for each mode. An effect that allows a player to change the
* target(s) of a modal spell or ability, or to choose new targets for a
* modal spell or ability, doesn't allow that player to change its mode.
* (See rule 700.2.)
* <p>
* 706.10c Some effects copy a spell or ability and state that its
* controller may choose new targets for the copy. The player may leave any
* number of the targets unchanged, even if those targets would be illegal.
* If the player chooses to change some or all of the targets, the new
* targets must be legal. Once the player has decided what the copy's
* targets will be, the copy is put onto the stack with those targets.
*
* @param game
* @param targetControllerId - player that can/has to change the target of
* the spell
* @param forceChange - does only work for targets with maximum of one
* targetId
* @param onlyOneTarget - 114.6b one target must be changed to another
* target
* @param newTargetFilterPredicate restriction for the new target (null - can select same targets)
* @return
*/
@Override
public boolean chooseNewTargets(Game game, UUID targetControllerId, boolean forceChange, boolean onlyOneTarget, Predicate<MageItem> newTargetFilterPredicate) {
Player targetController = game.getPlayer(targetControllerId);
if (targetController != null) {
StringBuilder oldTargetDescription = new StringBuilder();
StringBuilder newTargetDescription = new StringBuilder();
// Fused split spells or spells where "Splice on Arcane" was used can have more than one ability
Abilities<Ability> objectAbilities = new AbilitiesImpl<>();
if (this instanceof Spell) {
objectAbilities.addAll(((Spell) this).getSpellAbilities());
} else {
objectAbilities.add(getStackAbility());
}
for (Ability ability : objectAbilities) {
// Some spells can have more than one mode
for (UUID modeId : ability.getModes().getSelectedModes()) {
Mode mode = ability.getModes().get(modeId);
ability.getModes().setActiveMode(mode);
oldTargetDescription.append(ability.getTargetDescription(mode.getTargets(), game));
for (Target target : mode.getTargets()) {
Target newTarget = chooseNewTarget(targetController, ability, mode, target, forceChange, newTargetFilterPredicate, game);
// clear the old target and copy all targets from new target
target.clearChosen();
for (UUID targetId : newTarget.getTargets()) {
target.addTarget(targetId, newTarget.getTargetAmount(targetId), ability, game, false);
}
}
newTargetDescription.append(ability.getTargetDescription(mode.getTargets(), game));
}
}
if (!newTargetDescription.toString().equals(oldTargetDescription.toString()) && !game.isSimulation()) {
game.informPlayers(this.getLogName() + " is now " + newTargetDescription);
}
return true;
}
return false;
}
use of mage.abilities.Mode in project mage by magefree.
the class OrvarTheAllFormEffect method apply.
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
Spell spell = (Spell) this.getValue("spellCast");
if (player == null || spell == null) {
return false;
}
List<Predicate<Permanent>> predicates = spell.getSpellAbility().getModes().values().stream().map(Mode::getTargets).flatMap(Collection::stream).map(Target::getTargets).flatMap(Collection::stream).map(game::getPermanent).filter(Objects::nonNull).map(MageItem::getId).map(PermanentIdPredicate::new).collect(Collectors.toList());
if (predicates.isEmpty()) {
return false;
}
FilterPermanent filter = new FilterControlledPermanent("a permanent you control targeted by that spell");
filter.add(Predicates.or(predicates));
filter.add(Predicates.not(new MageObjectReferencePredicate(new MageObjectReference(source))));
TargetPermanent target = new TargetPermanent(filter);
target.setNotTarget(true);
player.choose(outcome, target, source.getSourceId(), game);
return new CreateTokenCopyTargetEffect().setTargetPointer(new FixedTarget(target.getFirstTarget(), game)).apply(game, source);
}
use of mage.abilities.Mode in project mage by magefree.
the class ChapterTriggeredAbility method addChapterEffect.
public void addChapterEffect(Card card, SagaChapter fromChapter, SagaChapter toChapter, Effects effects, Targets targets, boolean optional, Mode... modes) {
for (int i = fromChapter.getNumber(); i <= toChapter.getNumber(); i++) {
ChapterTriggeredAbility ability = new ChapterTriggeredAbility(null, SagaChapter.getChapter(i), toChapter, optional);
for (Effect effect : effects) {
if (effect != null) {
ability.addEffect(effect.copy());
}
}
for (Target target : targets) {
if (target != null) {
ability.addTarget(target.copy());
}
}
for (Mode mode : modes) {
ability.addMode(mode.copy());
}
if (i > fromChapter.getNumber()) {
ability.setRuleVisible(false);
}
card.addAbility(ability);
}
}
Aggregations