use of mage.choices.Choice in project mage by magefree.
the class TergridsLaternEffect method apply.
@Override
public boolean apply(Game game, Ability source) {
Player targetedPlayer = game.getPlayer(source.getTargets().getFirstTarget());
if (targetedPlayer == null) {
return false;
}
// AI hint to discard/sacrifice before die
Outcome aiOutcome = (targetedPlayer.getLife() <= 3 * 2) ? Outcome.Benefit : Outcome.Detriment;
Set<String> choiceSet = new HashSet<>();
if (game.getBattlefield().count(StaticFilters.FILTER_CONTROLLED_PERMANENT_NON_LAND, source.getSourceId(), targetedPlayer.getId(), game) > 0) {
choiceSet.add(SACRIFICE_CHOICE);
}
if (targetedPlayer.getHand().size() > 0) {
choiceSet.add(DISCARD_CHOICE);
}
choiceSet.add(LIFE_LOSS_CHOICE);
String chosen;
if (choiceSet.size() > 1) {
Choice choice = new ChoiceImpl(true);
choice.setChoices(choiceSet);
targetedPlayer.choose(aiOutcome, choice, game);
chosen = choice.getChoice();
if (chosen == null) {
// on disconnect
chosen = LIFE_LOSS_CHOICE;
}
} else {
chosen = LIFE_LOSS_CHOICE;
}
switch(chosen) {
case SACRIFICE_CHOICE:
TargetPermanent target = new TargetPermanent(StaticFilters.FILTER_CONTROLLED_PERMANENT_NON_LAND);
target.setNotTarget(true);
targetedPlayer.choose(Outcome.Sacrifice, target, source.getSourceId(), game);
Permanent chosenLand = game.getPermanent(target.getFirstTarget());
return chosenLand != null && chosenLand.sacrifice(source, game);
case DISCARD_CHOICE:
return targetedPlayer.discard(1, false, false, source, game).size() > 0;
case LIFE_LOSS_CHOICE:
return targetedPlayer.loseLife(3, game, source, false) > 0;
}
return false;
}
use of mage.choices.Choice in project mage by magefree.
the class UrzasAvengerEffect method init.
@Override
public void init(Ability source, Game game) {
super.init(source, game);
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Choice choice = new ChoiceImpl(true);
choice.setMessage("Choose one");
choice.setChoices(choices);
if (controller.choose(outcome, choice, game)) {
switch(choice.getChoice()) {
case "Banding":
gainedAbility = BandingAbility.getInstance();
break;
case "Flying":
gainedAbility = FlyingAbility.getInstance();
break;
case "First strike":
gainedAbility = FirstStrikeAbility.getInstance();
break;
default:
gainedAbility = TrampleAbility.getInstance();
break;
}
}
}
}
use of mage.choices.Choice in project mage by magefree.
the class VivienMonstersAdvocateTriggeredAbility method apply.
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
token.putOntoBattlefield(1, game, source, source.getControllerId());
for (UUID tokenId : token.getLastAddedTokenIds()) {
Permanent permanent = game.getPermanent(tokenId);
if (permanent == null) {
continue;
}
Choice choice = new ChoiceImpl(true);
choice.setMessage("Choose vigilance, reach, or trample counter");
choice.setChoices(choices);
player.choose(outcome, choice, game);
String chosen = choice.getChoice();
if (chosen != null) {
permanent.addCounters(CounterType.findByName(chosen.toLowerCase(Locale.ENGLISH)).createInstance(), source.getControllerId(), source, game);
}
}
return true;
}
use of mage.choices.Choice in project mage by magefree.
the class ContinuousEffects method asThough.
/**
* @param objectId object to check
* @param type
* @param affectedAbility null if check full object or ability if check only one ability from that object
* @param controllerId
* @param game
* @return sourceId of the permitting effect if any exists otherwise returns null
*/
public ApprovingObject asThough(UUID objectId, AsThoughEffectType type, Ability affectedAbility, UUID controllerId, Game game) {
// usage check: effect must apply for specific ability only, not to full object (example: PLAY_FROM_NOT_OWN_HAND_ZONE)
if (type.needAffectedAbility() && affectedAbility == null) {
throw new IllegalArgumentException("ERROR, you can't call asThough check to whole object, call it with affected ability instead: " + type);
}
// need it then disable that check or add extra param to AsThoughEffectType like needAffectedAbilityOrFullObject
if (!type.needAffectedAbility() && affectedAbility != null) {
throw new IllegalArgumentException("ERROR, you can't call AsThough check to affected ability, call it with empty affected ability instead: " + type);
}
List<AsThoughEffect> asThoughEffectsList = getApplicableAsThoughEffects(type, game);
if (!asThoughEffectsList.isEmpty()) {
MageObject objectToCheck;
if (affectedAbility != null) {
objectToCheck = affectedAbility.getSourceObject(game);
} else {
objectToCheck = game.getCard(objectId);
}
UUID idToCheck;
if (!type.needPlayCardAbility() && objectToCheck instanceof SplitCardHalf) {
// each split side uses own characteristics to check for playing, all other cases must use main card
// rules:
// 708.4. In every zone except the stack, the characteristics of a split card are those of its two halves combined.
idToCheck = ((SplitCardHalf) objectToCheck).getMainCard().getId();
} else if (!type.needPlayCardAbility() && objectToCheck instanceof AdventureCardSpell) {
// adventure spell uses alternative characteristics for spell/stack, all other cases must use main card
idToCheck = ((AdventureCardSpell) objectToCheck).getMainCard().getId();
} else if (!type.needPlayCardAbility() && objectToCheck instanceof ModalDoubleFacesCardHalf) {
// each mdf side uses own characteristics to check for playing, all other cases must use main card
// rules:
// "If an effect allows you to play a land or cast a spell from among a group of cards,
// you may play or cast a modal double-faced card with any face that fits the criteria
// of that effect. For example, if Sejiri Shelter / Sejiri Glacier is in your graveyard
// and an effect allows you to play lands from your graveyard, you could play Sejiri Glacier.
// That effect doesn't allow you to cast Sejiri Shelter."
idToCheck = ((ModalDoubleFacesCardHalf) objectToCheck).getMainCard().getId();
} else {
idToCheck = objectId;
}
Set<ApprovingObject> possibleApprovingObjects = new HashSet<>();
for (AsThoughEffect effect : asThoughEffectsList) {
Set<Ability> abilities = asThoughEffectsMap.get(type).getAbility(effect.getId());
for (Ability ability : abilities) {
if (affectedAbility == null) {
// applies to full object (one effect can be used in multiple abilities)
if (effect.applies(idToCheck, ability, controllerId, game)) {
if (effect.isConsumable() && !game.inCheckPlayableState()) {
possibleApprovingObjects.add(new ApprovingObject(ability, game));
} else {
return new ApprovingObject(ability, game);
}
}
} else {
// filter play abilities (no need to check it in every effect's code)
if (type.needPlayCardAbility() && !affectedAbility.getAbilityType().isPlayCardAbility()) {
continue;
}
if (effect.applies(idToCheck, affectedAbility, ability, game, controllerId)) {
if (effect.isConsumable() && !game.inCheckPlayableState()) {
possibleApprovingObjects.add(new ApprovingObject(ability, game));
} else {
return new ApprovingObject(ability, game);
}
}
}
}
}
if (possibleApprovingObjects.size() == 1) {
return possibleApprovingObjects.iterator().next();
} else if (possibleApprovingObjects.size() > 1) {
// Select the ability that you use to permit the action
Map<String, String> keyChoices = new HashMap<>();
for (ApprovingObject approvingObject : possibleApprovingObjects) {
MageObject mageObject = game.getObject(approvingObject.getApprovingAbility().getSourceId());
String choiceKey = approvingObject.getApprovingAbility().getId().toString();
String choiceValue;
if (mageObject == null) {
choiceValue = approvingObject.getApprovingAbility().getRule();
} else {
choiceValue = mageObject.getIdName() + ": " + approvingObject.getApprovingAbility().getRule(mageObject.getName());
}
keyChoices.put(choiceKey, choiceValue);
}
Choice choicePermitting = new ChoiceImpl(true);
choicePermitting.setMessage("Choose the permitting object");
choicePermitting.setKeyChoices(keyChoices);
Player player = game.getPlayer(controllerId);
player.choose(Outcome.Detriment, choicePermitting, game);
for (ApprovingObject approvingObject : possibleApprovingObjects) {
if (approvingObject.getApprovingAbility().getId().toString().equals(choicePermitting.getChoiceKey())) {
return approvingObject;
}
}
}
}
return null;
}
use of mage.choices.Choice in project mage by magefree.
the class GolemArtisanEffect method apply.
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source));
Player playerControls = game.getPlayer(source.getControllerId());
if (permanent != null && playerControls != null) {
Choice abilityChoice = new ChoiceImpl();
abilityChoice.setMessage("Choose an ability to add");
Set<String> abilities = new HashSet<>();
abilities.add(FlyingAbility.getInstance().getRule());
abilities.add(TrampleAbility.getInstance().getRule());
abilities.add(HasteAbility.getInstance().getRule());
abilityChoice.setChoices(abilities);
if (!playerControls.choose(Outcome.AddAbility, abilityChoice, game)) {
return false;
}
String chosen = abilityChoice.getChoice();
Ability ability = null;
if (FlyingAbility.getInstance().getRule().equals(chosen)) {
ability = FlyingAbility.getInstance();
} else if (TrampleAbility.getInstance().getRule().equals(chosen)) {
ability = TrampleAbility.getInstance();
} else if (HasteAbility.getInstance().getRule().equals(chosen)) {
ability = HasteAbility.getInstance();
}
if (ability != null) {
ContinuousEffect effect = new GainAbilityTargetEffect(ability, Duration.EndOfTurn);
game.addEffect(effect, source);
return true;
}
}
return false;
}
Aggregations