foul-magics/Mage/src/main/java/mage/abilities/effects/common/GainsChoiceOfAbilitiesEffect.java
ssk97 00770646f8
Create generic "Gains your choice of ability" effect, add [ACR] Assassin Initiate (#12619)
Create generic GainsChoiceOfAbilitiesEffect, covers both Target and Source cases.

Adds Assassin Initiate
2024-08-22 13:34:40 -07:00

141 lines
No EOL
5.1 KiB
Java

package mage.abilities.effects.common;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.targetpointer.FixedTargets;
import mage.util.CardUtil;
import java.util.*;
/**
* Something gains one ability of the player's choice from a list of abilities until end of turn.
* Affects any targets set and optionally the source as well. Have no targets to affect only the source.
*
* @author notgreat, TheElk801
*/
public class GainsChoiceOfAbilitiesEffect extends OneShotEffect {
public enum TargetType {
Source, Target, Both
}
private final Map<String, Ability> abilityMap;
private final boolean includeEnd;
private final TargetType affects;
private final String targetDescription;
public GainsChoiceOfAbilitiesEffect(Ability... abilities) {
this(TargetType.Target, null, true, abilities);
}
public GainsChoiceOfAbilitiesEffect(TargetType affects, Ability... abilities) {
this(affects, null, true, abilities);
}
public GainsChoiceOfAbilitiesEffect(TargetType affects, String targetDescription, boolean includeEnd, Ability... abilities) {
super(Outcome.AddAbility);
this.affects = affects;
this.targetDescription = targetDescription;
this.includeEnd = includeEnd;
this.abilityMap = new LinkedHashMap<>();
for (Ability ability : abilities) {
this.abilityMap.put(ability.getRule(), ability);
}
}
protected GainsChoiceOfAbilitiesEffect(final GainsChoiceOfAbilitiesEffect effect) {
super(effect);
this.affects = effect.affects;
this.abilityMap = CardUtil.deepCopyObject(effect.abilityMap);
this.targetDescription = effect.targetDescription;
this.includeEnd = effect.includeEnd;
}
@Override
public GainsChoiceOfAbilitiesEffect copy() {
return new GainsChoiceOfAbilitiesEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
List<Permanent> permanents = new ArrayList<>();
if (affects == TargetType.Source || affects == TargetType.Both) {
permanents.add(source.getSourcePermanentIfItStillExists(game));
}
if (affects == TargetType.Target || affects == TargetType.Both) {
for (UUID p : getTargetPointer().getTargets(game, source)) {
permanents.add(game.getPermanent(p));
}
}
permanents.removeIf(Objects::isNull);
if (player == null || permanents.isEmpty()) {
return false;
}
Choice choice = new ChoiceImpl(true);
choice.setMessage("Choose an ability to gain");
choice.setChoices(new HashSet<>(abilityMap.keySet()));
player.choose(outcome, choice, game);
Ability ability = abilityMap.get(choice.getChoice());
if (ability != null) {
game.addEffect(new GainAbilityTargetEffect(ability, Duration.EndOfTurn)
.setTargetPointer(new FixedTargets(permanents, game)), source);
}
return true;
}
@Override
public String getText(Mode mode) {
if (staticText != null && !staticText.isEmpty()) {
return staticText;
}
StringBuilder sb = new StringBuilder();
if (targetDescription != null) {
if (targetDescription.isEmpty()){
sb.append("gains");
} else {
sb.append(targetDescription);
sb.append(" gains");
}
} else switch (affects) {
case Source:
sb.append("{this} gains");
break;
case Target:
sb.append(getTargetPointer().describeTargets(mode.getTargets(), "that creature"));
sb.append(" gains");
break;
case Both:
sb.append("{this} and ");
sb.append(getTargetPointer().describeTargets(mode.getTargets(), "that creature"));
sb.append(" both gain");
break;
}
sb.append(" your choice of ");
String[] abilitiesText = abilityMap.keySet().toArray(new String[0]);
if (abilityMap.size() == 2) {
sb.append(abilitiesText[0]).append(" or ").append(abilitiesText[1]);
} else if (abilityMap.size() > 2) {
for (int i = 0; i < abilityMap.size() - 1; i += 1) {
sb.append(abilitiesText[i]).append(", ");
}
sb.append("or ").append(abilitiesText[abilityMap.size()-1]);
} else {
throw new IllegalStateException("Not enough abilities for GainsChoiceOfAbilitiesEffect");
}
if (includeEnd) {
sb.append(" until end of turn");
}
return sb.toString();
}
}